Notes4剑指offer_03-20题
Posted 码农编程录
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Notes4剑指offer_03-20题相关的知识,希望对你有一定的参考价值。
文章目录
3.数组中重复的数字
题目链接:https://leetcode-cn.com/problemset/lcof/
class Solution {
public int findRepeatNumber(int[] nums) {
Set<Integer> set =new HashSet<Integer>(); //实例化哈希表,set里每个元素只能存在一种
int res = -1;
for (int num : nums) //num in nums数组里
if(!set.add(num)) //add成功返回true,不成功返回false。这行返回不成功。
{
res = num;
break;
}
return res;
}
}
4.二维数组中的查找
class Solution {
public boolean findNumberIn2DArray(int[][] array, int target) {
//判断数组空 一维判断 || 二维判断 第一行长度=0
if((array==null||array.length==0)||(array.length==1&&array[0].length==0))
return false;
int i = 0, j = array[0].length - 1; // ij对应右上角
while(i <= array.length - 1 && j >= 0) // i行,j列
{
if(array[i][j] == target) return true; // 先判断是否相等,否则ij可能越界
if(array[i][j] > target) j --; // 排除列
else i ++; // 排除行
}
return false;
}
}
5.替换空格
请实现一个函数,把字符串 s 中的每个空格替换成"%20"。示例如下:
输入:s = “We are happy.”,输出:“We%20are%20happy.”
class Solution {
public String replaceSpace(String s) {
int n = s.length(); //对象调用方法,数组不用加括号
char[] array = new char[n * 3]; //一个空格替换为%20,长度为原来3倍
int size = 0;
for(int i = 0; i < n; i ++)
{
char c = s.charAt(i);
if(c == ' ')
{
array[size ++] = '%';
array[size ++] = '2';
array[size ++] = '0';
}
else
array[size ++] = c; //array里保存了替换好的字符串
}
String news = new String(array, 0 , size); //从0开始,长度为size
return news;
}
}
6.从尾到头打印链表
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。示例如下:
输入:head = [1,3,2],输出:[2,3,1]
class Solution {
public int[] reversePrint(ListNode head) {
//压栈
Stack<ListNode> stk = new Stack<ListNode>();
ListNode temp = head;
while(temp != null)//一直指向最后一个结点
{
stk.push(temp);
temp = temp.next;
}
int n = stk.size(); //必须用参数传递,不然会pop掉
int[] res = new int[n];
for(int i = 0; i < n; i ++)
res[i] = stk.pop().val; //val值
return res;
}
}
7.重建二叉树
class Solution {
//树 基本都要用到 递归
int preindex = 0; //记录下遍历到了哪一个
int inindex = 0; //遍历到传入数组长度preorder就结束了,记录是否结束的一个标志
public TreeNode buildTree(int[] preorder, int[] inorder) {
return dfs(preorder, inorder, null);
}
private TreeNode dfs(int[] preorder, int[] inorder, TreeNode finish)
{ //preorder前序,inorder中序
if(preindex == preorder.length || (finish != null && inorder[inindex] == finish.val))
return null;
//遍历过程
//前序 根左右
TreeNode root = new TreeNode(preorder[preindex ++]);
//左子树
root.left = dfs(preorder, inorder, root);
inindex ++;
//右子树
root.right = dfs(preorder, inorder, finish);
return root;
}
}
8.二叉树的下一个节点
class Solution {
public TreeNode inorderSuccessor(TreeNode p) {
//左根右
//中序遍历特点
//一个结点 有右子树 返回一定是 右子树 最左边的结点
if(p.right != null)
{
p = p.right;
while(p.left != null) p = p.left;
return p;
}
//没有右子树 返回的是 父亲结点
while(p.father != null)
{
if(p == p.father.left)
return p.father;
p = p.father;
}
return null;
}
}
9.用两个栈实现队列
class CQueue {
//栈 先进后出
//队列 先进先出
Stack<Integer> stk1, stk2;
int size;
public CQueue() {
stk1 = new Stack<Integer>();
stk2 = new Stack<Integer>();
size = 0;
}
public void appendTail(int value) {
//插入一个元素
//stk1保存 底部存新插入的 顶部存老的
while(!stk1.isEmpty())
stk2.push(stk1.pop());
stk1.push(value);
while(!stk2.isEmpty())
stk1.push(stk2.pop());
size ++;
}
public int deleteHead() {
//删除队列首部元素
//删除栈顶
if(size == 0)
return -1;
int res = stk1.pop();
size --;
return res;
}
}
10.斐波那契数列
class Solution {
public int fib(int n) {
if(n == 0) return 0;
if(n?==?1) return 1;
int first = 0, second = 1;
int res = 0;
for(int i = 2; i <= n; i ++)
{
res = (first + second) % 1000000007;
first = second % 1000000007;
second = res % 1000000007;
}
return res % 1000000007;
}
}
11.旋转数组的最小数字
class Solution {
public int minArray(int[] nums) {
int n = nums.length - 1;
if(n < 0) return -1;
while(n > 0 && nums[n] == nums[0]) n --;
if(nums[n] >= nums[0]) return nums[0];
int l = 0, r = n;
while(l < r)
{
int mid = l + r >> 1; //[l, mid] [mid + 1, r]
if(nums[mid] < nums[0]) r = mid;
else l = mid + 1;
}
return nums[l];
}
}
12.矩阵中的路径
class Solution {
//回溯法 dfs
public boolean exist(char[][] board, String word) {
for(int i = 0; i < board.length; i ++)
for(int j = 0; j < board[0].length; j ++)
if(dfs(board, word, 0, i, j))
return true;
return false;
}
private boolean dfs(char[][] board, String word, int u, int x, int y)
{
//先判断边界 后比较相等
if(x >= board.length || x < 0 || y >= board[0].length || y < 0 || board[x][y] != word.charAt(u))
return false;
if(u == word.length() - 1) return true;
char temp = board[x][y];
board[x][y] = '*';
//递归遍历
boolean res = dfs(board, word, u + 1, x - 1, y) || dfs(board, word, u + 1, x + 1, y) || dfs(board, word, u + 1,x, y - 1) || dfs(board, word, u + 1, x, y + 1);
board[x][y] = temp;
return res;
}
}
13.机器人的运动范围
class Solution {
int m, n, k;
boolean[][] visited;
public int movingCount(int m1, int n1, int k1) {
//找规律
//19 20 小8
//39 40 小8
//x9 x+1 0 小8
//普通情况 12 13 +1
m = m1;
n = n1;
k = k1;
visited = new boolean[m][n];//false
return dfs(0, 0, 0, 0);
}
private int dfs(int x, int y, int sx, int sy)
{
//sx sy对应 x y数位之和
// x 16 y 20 sx 7 sy 2
//边界优先 m- 1 n -1
if(x >= m || y >= n || k < sx + sy || visited[x][y]) return 0;
visited[x][y] = true;
//sx + sy <= k
return 1 + dfs(x + 1, y, (x + 1) % 10 != 0 sx + 1 : sx - 8 , sy)
+ dfs(x, y + 1, sx, (y + 1) % 10 != 0 sy + 1 : sy - 8);
}
}
14.剪绳子
class Solution {
public int cuttingRope(int n) {
if (n < 2) {
return 0;
}
int[] dp = new int[n + 1];
dp[2] = 1;
for (int i = 3; i <= n; i++) {
for (int j = 1; j < i; j++) {
dp[i] = Math.max(Math.max(j * dp[i - j], j * (i - j)), dp[i]);
}
}
return dp[n];
}
}
15.二进制中1的个数
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
//n & (n - 1)
//每执行一次 最右边的1变成0
//unsigned int
int count = 0;
while(n != 0)
{
count ++;
n = n & (n - 1);
}
return count;
}
}
16.数值的整数次方
class Solution {
public double myPow(double x, int n) {
//快速幂
//n用二进制表示
if(x == 0) return 0;
long b = n;// 2147483648,2147483647
double res = 1.0;
if(b < 0)
{
b = -b;//用long防止溢出
x = 1 / x;
}
//快速幂
while(b > 0)
{
if((b & 1) == 1) res *= x;//累乘
x *= x;以上是关于Notes4剑指offer_03-20题的主要内容,如果未能解决你的问题,请参考以下文章