classSolution{publicintfindRepeatNumber(int[] nums){// 数组的length是属性int n = nums.length;for(int i =0; i < n;){if(nums[i]!= i && nums[nums[i]]!= nums[i]){//交换int t = nums[nums[i]];
nums[nums[i]]= nums[i];
nums[i]= t;}elseif(nums[i]!= i && nums[nums[i]]== nums[i])return nums[i];elseif(nums[i]==i) i++;}return-1;}}
04 二维数组中的查找
classSolution{publicbooleanfindNumberIn2DArray(int[][] matrix,int target){// 从右上角或者左下角开始 此处从右上角开始int m = matrix.length;if(m==0)returnfalse;int n = matrix[0].length;int i =0, j = n-1;while(i < m && j >=0){if(matrix[i][j]> target) j--;elseif(matrix[i][j]< target) i++;elsereturntrue;}returnfalse;}}
替换空格
classSolution{public String replaceSpace(String s){int n = s.length();
String res ="";for(int i =0; i < n; i++){if(s.charAt(i)!=' '){
res += s.charAt(i);}else res+="%20";}return res;}}
从尾到头打印链表
考点:链表
思路:反转链表,用递归实现逆序
classSolution{
ArrayList<Integer> list =newArrayList<>();publicint[]reversePrint(ListNode head){//用递归实现逆序reverse(head);int[] temp =newint[list.size()];for(int i =0; i < list.size(); i++){
temp[i]= list.get(i);}return temp;}voidreverse(ListNode head){if(head == null)return;reverse(head.next);
list.add(head.val);}}
07. 重建二叉树
注意边界
先对中序遍历存储值和下标的映射,可以提高效率
classSolution{int[] preorder;int[] inorder;
HashMap<Integer, Integer> mp;public TreeNode buildTree(int[] preorder,int[] inorder){//重建二叉树this.preorder = preorder;this.inorder = inorder;
mp =newHashMap<>();for(int i =0; i < inorder.length; i++){
mp.put(inorder[i], i);}returndfs(0, preorder.length-1,0, inorder.length-1);}public TreeNode dfs(int pl,int pr,int il,int ir){if(pl > pr)return null;
TreeNode root =newTreeNode(preorder[pl]);int k = mp.get(root.val);int left = k - il;
root.left =dfs(pl+1, pl+left, il, k-1);
root.right =dfs(pl+left+1, pr, k+1, ir);return root;}}
classSolution{/*100以内的斐波那契数列可以用long处理*/finalint MOD =1000000007;long[] f =newlong[103];publicintfib(int n){
f[0]=0;
f[1]=1;for(int i =2; i <= n;++i){
f[i]=(f[i-1]+ f[i-2])% MOD;}return(int)f[n];}}
10- II. 青蛙跳台阶问题
classSolution{/*100以内的斐波那契数列可以用long处理*/finalint MOD =1000000007;long[] f =newlong[103];publicintnumWays(int n){
f[0]=1;
f[1]=1;
f[2]=2;for(int i =2; i <= n;++i){
f[i]=(f[i-1]+ f[i-2])% MOD;}return(int)f[n];}}
11. 旋转数组的最小数字
考点:二分法
注意:收尾存在重复数值,需要先将数组变成分段的形式才能使用二分。
classSolution{publicintminArray(int[] nums){int end = nums.length-1;if(end==-1)return-1;while(end >=0&& nums[0]==nums[end])--end;int i =0, j = end;while(i < j){int mid =(i + j)>>1;if(nums[mid]<= nums[end]) j = mid;else i = mid +1;}return nums[i];}}
classSolution{/**
* 深度搜索+回溯
* */publicbooleanexist(char[][] board, String word){for(int i =0; i < board.length;++i){for(int j =0; j < board[i].length;++j){if(dfs(board, word, i, j,0))returntrue;}}returnfalse;}int dx[]={1,-1,0,0};int dy[]={0,0,1,-1};booleandfs(char[][] board, String word,int x,int y,int u){/**
* 只有一个元素时,进来就要先判断,在处理四周的元素。
* */if(board[x][y]!= word.charAt(u))returnfalse;if(u == word.length()-1)returntrue;char c = board[x][y];
board[x][y]='.';for(int i =0; i <4;++i){int a = dx[i]+ x;int b = dy[i]+ y;if(a >=0&& a < board.length && b >=0&& b < board[a].length){if(dfs(board, word, a, b, u+1))returntrue;}}
board[x][y]= c;returnfalse;}}
剑指 Offer 13. 机器人的运动范围
思路
不需要回溯
classSolution{public:int dx[4]={1,-1,0,0};int dy[4]={0,0,1,-1};int res =0;int st[105][105];intmovingCount(int m,int n,int k){memset(st,0,sizeof st);dfs(m, n,0,0, k);return res;}voiddfs(int m,int n,int x,int y,int k){if(x <0|| x >= m || y <0|| y >= n ||getBitSum(x, y)> k || st[x][y])return;
res ++;
st[x][y]=true;for(int i =0; i <4; i++){int a = dx[i]+ x;int b = dy[i]+ y;dfs(m, n, a, b, k);}}intgetBitSum(int x,int y){return x/100+ x%100/10+ x%10+ y/100+ y%100/10+ y%10;}};
剑指 Offer 14- I. 剪绳子
数学思维:智力题
classSolution{public:intcuttingRope(int n){/*数学题 只包含2和3 并且最多两个2 ni >= 5 3*(ni-3) >= ni 4 = 2*2 2*2*2 < 3 * 3 */if(n <=3)return n -1;int res =1;if(n %3==1) res*=4, n-=4;if(n %3==2) res*=2, n-=2;while(n) res*=3, n-=3;return res;}};
剑指 Offer 14- II. 剪绳子 II
注意转换为long long再取模,不然会溢出。
classSolution{public:constint MOD =1e9+7;intcuttingRope(int n){if(n <=3)return n-1;longlong res =1;if(n%3==1) res*=4, n-=4;if(n%3==2) res*=2, n-=2;while(n) res=res*3% MOD, n-=3;return res;}};
classSolution{public:inthammingWeight(uint32_t n){int count =0;for(int i =0; i <32; i++){if((n>>i)&1) count++;}return count;}};
剑指 Offer 16. 数值的整数次方
快速幂
把指数值转换成了二进制的位数,极大的加快了计算速度。logn
classSolution{public:doublemyPow(double x,int n){//快速幂if(n==0)return1.0;longlong t = n >0? n:-(longlong) n;double res =1;while(t){if(t&1) res *= x;
x *= x;
t >>=1;}if(n <0) res =1/res;return res;}};
剑指 Offer 17. 打印从1到最大的n位数
太简单
classSolution{public:
vector<int>printNumbers(int n){
vector<int> v;constint t =pow(10, n);for(int i =1; i < t; i++){
v.push_back(i);}return v;}};
classSolution{public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB){auto p = headA, q = headB;while(p != q){if(!p) p = headB;else p = p->next;if(!q) q = headA;else q = q->next;}return p;}};
找到两个只出现一次的数字
思路:异或这两个数字,找到第一个不同的位,以这个位作为划分规则。
publicclassSolution{/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param array int整型一维数组
* @return int整型一维数组
*/publicint[] FindNumsAppearOnce (int[] array){int ans =0;for(int i =0; i < array.length; i++){
ans ^= array[i];}int t = ans, k =0;while(t !=0){if(t%2==1){break;}
t /=2;
k++;}int sum =0;for(int i =0; i < array.length; i++){if(((array[i]>>>k)&1)==1) sum ^= array[i];}int a = Math.min(sum, ans^sum);int b = Math.max(sum, ans^sum);returnnewint[]{a, b};}}