1 数组中的重复数字

题目

在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

思路

所有的数字都在0到n-1,所以可以将数字看做数组的下标。
通过把每个数字放回它的值作为索引的位置,在放置的时候判断目标位置是否已经有正确对应的值
如果没有,就交换,如果有,说明对应位置存在重复值。

代码

class Solution {public int findRepeatNumber(int[] nums) {for(int i =0;i<nums.length;i++){//如果当前数不是应该在的位置,就放过去,交换对应位置的数回来//如果在应该在的位置,这个就跳过去,看下一个。if(nums[i]!=i){int temp = nums[nums[i]];//移动时如果目标位置已经有了一个应该在的数,说明重复了if(temp == nums[i]){return nums[i];}//没有就交换一下nums[nums[i]]=nums[i];nums[i]=temp;i--;}}return 0;}
}

2 二维数组中的查找

题目

在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

思路

代码

class Solution {public boolean findNumberIn2DArray(int[][] matrix, int target) {int row = matrix.length-1;int col = 0;while(row >=0&&col<matrix[0].length){if(matrix[row][col]==target)return true;if(matrix[row][col]>target){row = row -1;}else{col = col+1;}}return false;}
}

3 替换空格

题目

请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

代码

class Solution {public String replaceSpace(String s) {if(s.length()==0)return s;int count =0;//求一下空格的个数确定 array的sizefor(int i= 0;i<s.length();i++)if(s.charAt(i) == ' ')count++;int size = s.length()+count*2;char [] str = new char[size];int j=size-1;//从后往前填写,其实在这道题从前往后也是一样的,从后往前在某些情境下可以实现原地for(int i =s.length()-1;i>=0;i--){if(s.charAt(i)==' '){str[j]='0';str[j-1]='2';str[j-2]='%';j=j-3;}else{str[j]=s.charAt(i);j--;}}return new String(str);}
}

4 从尾到头打印链表

题目

输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。

代码

/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode(int x) { val = x; }* }*/
class Solution {//记录长度  创建返回结果 填入即可  当然 链表反转也可以解决public int[] reversePrint(ListNode head) {int len=0;ListNode cur=head;while(cur!=null){len++;cur=cur.next;}int []res=new int[len];for(int i=len-1;i>=0;i--){res[i]=head.val;head=head.next;}return res;}
}

5 重建二叉树

题目

输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

代码

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode(int x) { val = x; }* }*/
class Solution {public TreeNode buildTree(int[] preorder, int[] inorder) {return rebuild(preorder,inorder,0,preorder.length,0,preorder.length);}public TreeNode rebuild(int [] preOrder, int []inOrder,int lp,int rp,int li,int ri){if(lp>=rp||li>=ri)return null;TreeNode node = new TreeNode(preOrder[lp]);int count = 0;for(int i = li;i<ri;i++){if(inOrder[i]==preOrder[lp])break;count++;}node.left = rebuild(preOrder,inOrder,lp+1,lp+1+count,li,li+count);node.right=rebuild(preOrder,inOrder,lp+count+1,rp,li+count+1,ri);return node;}
}

6 用两个栈实现队列

题目

用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )

代码

    class CQueue {public Stack<Integer> inStack;public Stack<Integer> outStack;public CQueue() {inStack= new Stack();outStack=new Stack();}public void appendTail(int value) {while(outStack.size()!=0){inStack.push(outStack.pop());}inStack.push(value);}public int deleteHead() {while(inStack.size()!=0){outStack.push(inStack.pop());}if(outStack.size()!=0)return outStack.pop();elsereturn -1;}}/*** Your CQueue object will be instantiated and called as such:* CQueue obj = new CQueue();* obj.appendTail(value);* int param_2 = obj.deleteHead();*/

7 斐波那契数列

题目

写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项。斐波那契数列的定义如下:
F(0) = 0, F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.
斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。
答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

代码

class Solution {public int fib(int n) {int first = 0;int second = 1;if(n==0)return 0;if(n==1)return 1;if(n==2)return 1;int third = 0;for(int i =2 ;i<=n;i++){third = (first+second)%1000000007;first = second;second = third;}return third;}
}

8 青蛙跳台阶

题目

一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。
答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

代码

class Solution {public int numWays(int n) {if(n==0)return 1;if(n==1)return 1;int first = 1,second =1;int third = 2;for(int i=2;i<=n;i++){third = (first+second)%1000000007;first=second;second=third;}return third;}
}

9 旋转数组中的最小数字(有点东西)

题目

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。

代码

class Solution {public int minArray(int[] numbers) {int left = 0,right = numbers.length-1;while(left+1<right){int index = left+(right-left)/2;if(numbers[index]>numbers[right]){left = index;}else if(numbers[index]<numbers[right])right =index;elseright--;}if(numbers[left]<numbers[right])return numbers[left];else{return numbers[right];}}
}

10 矩阵中的路径

题目

请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如,在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字母用加粗标出)。
[[“a”,“b”,“c”,“e”],
[“s”,“f”,“c”,“s”],
[“a”,“d”,“e”,“e”]]
但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。

代码

class Solution {//设定两个全局的标记public boolean success= false;public boolean[][] flag;public boolean exist(char[][] board, String word) {//避免一下错误输入if(board.length<=0||board[0].length<=0)return false;//根据输入初始化标记数组flag = new boolean [board.length][board[0].length];//所有元素作为入口for(int i = 0;i<board.length;i++){for(int j=0;j<board[0].length;j++){move(board,i,j,word,0);}}return success;}public void move(char [][]board,int i,int j,String word, int index){//有一个成功就不继续了if(success == true)return ;//走完word就是成功if(index == word.length()){success = true;return ;}//越界情况处理掉if(i<0||i>=board.length||j<0||j>=board[0].length)return;//如果flag表示没走过这个点且这个点和word当前字符相同,那就往上下左右继续走if(flag[i][j]==false&&board[i][j]==word.charAt(index)){flag[i][j]=true;move(board,i+1,j,word,index+1);move(board,i-1,j,word,index+1);move(board,i,j+1,word,index+1);move(board,i,j-1,word,index+1);//走完说明上下左右没有匹配到,这个点标记恢复标记,退回上一步的节点继续走flag[i][j]=false;}}
}

11 机器人的运动范围

题目

地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?

代码

class Solution {//要考虑好最重要的就是走过的路能不能走的问题,实际上遍历就是不能往回走的,但是一样可以遍历到所有的路,还是深度优先遍历没有理解好int count = 0;boolean [][]flag;public int movingCount(int m, int n, int k) {//初始化一个标记数组flag = new boolean[m][n];move(m,n,k,0,0);return count;}public void move(int m,int n,int k,int x,int y){//越界不继续if(x<0||x>=m||y<0||y>=n)return ;//走过不走if(flag[x][y]==true){return;}//如果符合要求就走进来,然后上下左右。if(k>=count(x,y)){flag[x][y]=true;count++;move(m,n,k,x+1,y);move(m,n,k,x-1,y);move(m,n,k,x,y-1);move(m,n,k,x,y+1);}}//实际的业务要求独立出来public int count(int x,int y){int sum =0;while(x>0){sum+=x%10;x=x/10;}while(y>0){sum+=y%10;y=y/10;}return sum;}
}

12 剪绳子I

题目

给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]…k[m-1] 。请问 k[0]k[1]…*k[m-1] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。

代码

class Solution {public int cuttingRope(int n) {//简单数学证明一下切3 切2 的大小比较if(n==2)return 1;if(n==3)return 2;if(n==4)return n;int sum =1;while(n>=5){sum=sum*3;n=n-3;}if(n>0){sum*=n;}return sum;}
}

13 剪绳子 II

题目

给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]…k[m - 1] 。请问 k[0]k[1]…*k[m - 1] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。

答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

代码

class Solution {public int cuttingRope(int n) {//简单证明一下切3 切2 的大小比较if(n==2)return 1;if(n==3)return 2;if(n==4)return n;//这里防止溢出long sum =1;while(n>=5){//这里乘三有溢出的情况,所以取余也莫得用sum=sum*3%1000000007;n=n-3;}if(n>0){sum=sum*n%1000000007;}return (int)sum;}
}

14 二进制中1的个数

题目

请实现一个函数,输入一个整数,输出该数二进制表示中 1 的个数。例如,把 9 表示成二进制是 1001,有 2 位是 1。因此,如果输入 9,则该函数输出 2。

代码

public class Solution {// you need to treat n as an unsigned valuepublic int hammingWeight(int n) {//n是整数,但是负整数也是整数//仗着java有无符号右移,所以这个问题被掩盖了        int count =0;while(n!=0){if((n&1)==1){count++;}n=n>>>1;}return count;}
}
//如果不用无符号右移
public class Solution {// you need to treat n as an unsigned valuepublic int hammingWeight(int n) {//n是整数,但是负整数也是整数//仗着java有无符号右移,所以这个问题被掩盖了int count =0;for(int i=0;i<32;i++){if((n&1)==1){count++;}n=n>>1;}return count;}
}

15 数值的整数次方

题目

实现函数double Power(double base, int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。

代码

class Solution {public double myPow(double x, int n) {if(n==0)return 1;boolean flag = false;if(n<0){//这里处理负最大转正溢出问题//大部分数据不收到具体负数值影响(因为没有大数)//只有0  1 -1受到影响,所以正负和奇偶注意一下即可if(n==Integer.MIN_VALUE)n=n+2;n=-n;flag = true;}double ans =  pow(x,n);if(flag){if(ans== 0)return 0;ans=1/ans;}return ans;}public double pow(double x,int n){double tempAns=1;while(n>1){if(n%2==1){tempAns*=x;n=n-1;}x*=x;n=n/2;}tempAns =x*tempAns;return tempAns;}
}

16 打印从1到最大的n位数(本身在剑指offer是一个字符串加法问题)

题目

输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999。

代码

class Solution {public int[] printNumbers(int n) {  int size= (int)Math.pow(10,n);int []res = new int [size-1];for(int i =1;i<size;i++){res[i-1]=i;  }return res;}
}

17 删除链表中的节点

题目

给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。
返回删除后的链表的头节点。

代码

/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode(int x) { val = x; }* }*/
class Solution {public ListNode deleteNode(ListNode head, int val) {if(head==null) return null;ListNode dummy = new ListNode(0);dummy.next = head;ListNode cur = dummy;while(cur.next!=null){if(cur.next.val==val){cur.next=cur.next.next;return dummy.next;}cur=cur.next;} return dummy.next;}
}

18 正则表达式匹配

题目

代码

19 表示字符的字符串

题目

代码

20 调整数组,使奇数位于偶数前

题目

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分

代码

class Solution {public int[] exchange(int[] nums) {int left = 0,right = nums.length-1;while(left<right){while(left<right&&(nums[left]&1)==1){left++;}while((nums[right]&1)==0&&right>left){right--;}int temp = nums[left];nums[left]=nums[right];nums[right]=temp;}return nums;}
}

21 链表中倒数第K个节点

题目

输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。例如,一个链表有6个节点,从头节点开始,它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个节点是值为4的节点。

代码

/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode(int x) { val = x; }* }*/
class Solution {public ListNode getKthFromEnd(ListNode head, int k) {//判断一下k的情况if(k<0)return null;ListNode dummy = new ListNode(0);dummy.next = head;ListNode fast= dummy;ListNode slow = dummy;for(int i =0;i<k;i++){//避免k大于链表总个数 直接走出去了if(fast.next!=null)fast=fast.next;elsereturn null;}while(fast!=null){fast=fast.next;slow = slow.next;}return slow;}
}

22 反转链表

题目

定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

代码

/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode(int x) { val = x; }* }*/
class Solution {public ListNode reverseList(ListNode head) {if(head==null)return null;ListNode dummy = null;ListNode pre = dummy,cur = head,nxt = head.next;while(cur!=null){nxt = cur.next;cur.next =pre;pre = cur;cur = nxt;}return pre;}
}

23 合并两个排序链表

题目

输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。

代码

/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode(int x) { val = x; }* }*/
class Solution {public ListNode mergeTwoLists(ListNode l1, ListNode l2) {//虚拟头节点  弄个cur指针更新ListNode dummy = new ListNode(0);ListNode cur = dummy;//有一个还有就继续while(l1!=null||l2!=null){//如果是空了就一直用最大的模拟int val1 = l1==null?Integer.MAX_VALUE:l1.val;int val2 = l2==null?Integer.MAX_VALUE:l2.val;if(val1<val2){cur.next = l1;cur=cur.next;l1=l1.next;}else if (val2 < val1){cur.next = l2;cur=cur.next;l2=l2.next;}//如果相等了要考虑一下是不是模拟和 真实都为MAX_VALUEelse{//如果是MAX_VALUE就要判断一下是不是有人是虚拟出来的值if(val1 ==Integer.MAX_VALUE){if(l1==null){cur.next = l2;cur=cur.next;l2=l2.next;}else{cur.next = l1;cur=cur.next;l1=l1.next;}}//如果不是MAX_VALUE就随便选一个cur.next = l2;cur=cur.next;l2=l2.next;}}return dummy.next;}
}

24 树的子结构

题目

输入两棵二叉树A和B,判断B是不是A的子结构。(约定空树不是任意一个树的子结构)
B是A的子结构, 即 A中有出现和B相同的结构和节点值。
例如:
给定的树 A:
3
/
4 5
/
1 2
给定的树 B:
4
/
1
返回 true,因为 B 与 A 的一个子树拥有相同的结构和节点值。

代码

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode(int x) { val = x; }* }*/
class Solution {public boolean isSubStructure(TreeNode A, TreeNode B) {//根据题意空不行if(B==null) return false;//外层就对A遍历,所有节点作为根节点试一下和B匹配boolean root = isSame(A,B);boolean l=false,r=false;if(A.left!=null)l= isSubStructure(A.left,B);if(A.right !=null)r = isSubStructure(A.right,B);return root||l||r;}//最开始理解错了所以叫了same,其实还是子结构,只不过是以A为根节点和以B为根节点的子结构public boolean isSame(TreeNode A,TreeNode B){//条件判断,B可以为空,A可以有多余的,但是A空B不空不行if(B==null)return true;if(B!=null &&A==null)return false;if(A.val == B.val){return isSame(A.left,B.left)&&isSame(A.right,B.right);}return false;}
}

25 二叉树的镜像

题目

请完成一个函数,输入一个二叉树,该函数输出它的镜像。

例如输入:
4
/
2 7
/ \ /
1 3 6 9
镜像输出:
4
/
7 2
/ \ /
9 6 3 1

代码

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode(int x) { val = x; }* }*/
class Solution {public TreeNode mirrorTree(TreeNode root) {//先把空处理掉,所以进入mirror的都不是空节点了if(root ==null) return null;mirror(root);//如果有左右节点,也要做一下镜像操作,注意是外层mirrorTree 而不是直接mirrorif(root.left != null)mirrorTree(root.left);if(root.right !=null)mirrorTree(root.right);return root;}public void mirror(TreeNode root){TreeNode temp = root.right;root.right = root.left;root.left = temp;}
}

26 对称的二叉树

题目

请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
1
/
2 2
/ \ /
3 4 4 3
但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:
1
/
2 2
\
3 3

代码

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode(int x) { val = x; }* }*/
class Solution {//这道题初看起来就不是左右子树递归的题,因为没有子问题的感觉//但是实际上是一个遍历左右子树比较的问题public boolean isSymmetric(TreeNode root) {if(root ==null )return true;return ismirror(root.left,root.right);}public boolean ismirror(TreeNode left,TreeNode right){if(left==null&&right == null)return true;if(left ==null || right == null)return false;if(left.val!=right.val)return false;return ismirror(left.left,right.right)&&ismirror(left.right,right.left);}
}

27 顺时针打印矩阵

题目

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。

代码

class Solution {//这个解法是java课上听同学的解法,感觉很巧妙很清晰//维护四个标记,上下左右,然后更新四个边界//标记互相覆盖的时候就是结束了,相等可以 说明还有一行public int[] spiralOrder(int[][] matrix) {if(matrix.length==0||matrix[0].length==0)return new int[0];int [] ans = new int [matrix.length*matrix[0].length];int index= 0;int up= 0,down = matrix.length-1;int left = 0,right = matrix[0].length-1;while(up<=down &&left <=right){for(int i =left;i<=right;i++){ans[index++]=matrix[up][i];}up++;if(up>down) break;for(int i=up;i<=down;i++){ans[index++]=matrix[i][right];}right--;if(left>right)break;for(int i =right;i>=left;i--){ans[index++]=matrix[down][i];}down--;if(up>down)break;for(int i=down;i>=up;i--){ans[index++]=matrix[i][left];}left++;}return ans;}
}

28 包含min函数的栈

题目

定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。

代码

class MinStack {/** initialize your data structure here. *///这里经常会在声明Stack的时候忘记加Integer,导致比较x 的时候类型报错public Stack <Integer>minStack;public Stack <Integer>stk ;public MinStack() {minStack = new Stack();stk = new Stack();}public void push(int x) {stk.push(x);//这里要看一下是不是有元素,没有元素肯定直接放,有元素要比一下if(minStack.size()==0){minStack.push(x);}else{if(x<minStack.peek()){minStack.push(x);}else{minStack.push(minStack.peek());}}}public void pop() {stk.pop();minStack.pop();}public int top() {return stk.peek();}public int min() {return minStack.peek();}
}/*** Your MinStack object will be instantiated and called as such:* MinStack obj = new MinStack();* obj.push(x);* obj.pop();* int param_3 = obj.top();* int param_4 = obj.min();*/

29 栈的压入弹出序列

题目

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如,序列 {1,2,3,4,5} 是某栈的压栈序列,序列 {4,5,3,2,1} 是该压栈序列对应的一个弹出序列,但 {4,3,5,1,2} 就不可能是该压栈序列的弹出序列。

代码

class Solution {//模拟一下即可public boolean validateStackSequences(int[] pushed, int[] popped) {Stack <Integer> stk = new Stack<>();if(popped.length!=pushed.length)return false;int index= 0;for( int i = 0 ;i<pushed.length;i++){//这里考虑一下index的范围是否需要限制一下,如果输入合理不需要//所以最好在上面判断一下size是否相同,可以保证index不会越界if(pushed[i]==popped[index]){index++;while(stk.size()!=0&&stk.peek()==popped[index]){stk.pop();index++;}}else{stk.push(pushed[i]);}}if(index== popped.length&&stk.size()==0)return true;else return false;}
}

30 从上到下打印二叉树I

题目

从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。

代码

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode(int x) { val = x; }* }*/
class Solution {//这道题就拿队列做一个层次遍历即可public int[] levelOrder(TreeNode root) {Queue<TreeNode> queue= new LinkedList<>();if(root==null)return (new int[0]);queue.add(root);ArrayList<Integer> reslist=new ArrayList<>();while(queue.size()>=1){TreeNode temp=queue.poll();reslist.add(temp.val);if(temp.left!=null){queue.add(temp.left);}if(temp.right!=null){queue.add(temp.right);}}int []res = new int[reslist.size()];for(int i=0;i<reslist.size();i++){res[i]=reslist.get(i);}return res;}
}

31 从上到下打印二叉树II

题目

从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。

代码

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode(int x) { val = x; }* }*/
class Solution {public List<List<Integer>> levelOrder(TreeNode root) {//构造返回结果List<List<Integer>> res= new LinkedList<>();//特判不能丢if(root ==null)return res;//终归是层次遍历,只不过要记录层次 通过queue的size记录每一层的个数Queue<TreeNode>queue = new LinkedList<>();queue.offer(root);int size = queue.size();//这里可以直接用size判断是否为空了while(size>0){List<Integer> row= new LinkedList<>();for(int i =0;i<size;i++){//里面是老一套TreeNode temp = queue.poll();row.add(temp.val);if(temp.left!=null) queue.offer(temp.left);if(temp.right!=null) queue.offer(temp.right);}res.add(row);size= queue.size();}return res;}}

32 从上到下打印二叉树III

题目

请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。

代码

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode(int x) { val = x; }* }*/
class Solution {public List<List<Integer>> levelOrder(TreeNode root) {List<List<Integer>> res =new ArrayList<>();if(root ==null)return res;Queue<TreeNode> que = new LinkedList<>();que.offer(root);int size = que.size();//对于这种Z型的 flag=!flag的方法还是舒服的boolean flag=false;while(size>0){List<Integer>temp = new ArrayList<>();for(int i=0;i<size;i++){TreeNode tempNode =que.poll();temp.add(tempNode.val);if(tempNode.left!=null)que.offer(tempNode.left);if(tempNode.right!=null)que.offer(tempNode.right);}size=que.size();if(flag==true){//灵魂一句Collections.reverse(temp);}flag = !flag;res.add(temp);}return res;}
}

33 二叉搜索树后续遍历序列

题目

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。

代码

class Solution {//二叉搜索树左子树比root小,右子树比root大这个是判断标准//所以只要能按照左右根的方式划分出正确大小的范围即可//递归解决显然更合适,root能划,所有子节点都能划分//递归终点就是只有两个点时肯定ok,因为一个是根,另一个大小无所谓public boolean verifyPostorder(int[] postorder) {return isBinaryTree(postorder,0,postorder.length-1);}//记录数组的索引,确定讨论范围public boolean isBinaryTree(int []postorder,int left,int right){if(right-left<=1){return true;}int root = postorder[right];int nextLeft=right-1;int nextRight=right-1;//flag就标记一下是不是已经到了右子树的范围,右子树内不能出现小于root的情况boolean flag = false;for(int i =left;i<=right-1;i++){if(flag == true && postorder[i]<root)return false;if(flag==false&&postorder[i]>root){nextRight=i-1;nextLeft=i;flag=true;}}//这就是自己的范围符合了,子集中子树的范围也得符合才是二叉搜索树return isBinaryTree(postorder,left,nextRight)&&isBinaryTree(postorder,nextLeft,right-1);}
}

34 二叉树中和为某一值的路径

题目

输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径。从树的根节点开始往下一直到叶节点所经过的节点形成一条路径。

代码

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode(int x) { val = x; }* }*/
class Solution {public List<List<Integer>> res = new LinkedList<>();//因为要用clone方法,所以这里要声明为具体的linkedList类型public LinkedList<Integer> temp= new LinkedList<>();public List<List<Integer>> pathSum(TreeNode root, int sum) {if(root==null) return res;search(root,sum);return res;}public void search(TreeNode root , int sum){temp.add(root.val);//这里说明sum和叶节点的值相等,路径符合要求if(sum==root.val&&root.left==null&&root.right==null){res.add((LinkedList<Integer>)temp.clone());}  if(root.left!=null) search(root.left,sum-root.val);if(root.right!=null) search(root.right,sum-root.val);//得恢复现场temp.remove(temp.size()-1);}
}

35 复杂链表的复制

题目

请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。

代码

/*
// Definition for a Node.
class Node {int val;Node next;Node random;public Node(int val) {this.val = val;this.next = null;this.random = null;}
}
*/
class Solution {public Node copyRandomList(Node head) {if(head == null) return head;Node cur = head;//先复制一个在后面挂着while(cur!=null){Node copy = new Node(cur.val);copy.next = cur.next;cur.next=copy;cur=cur.next.next;}//再复制random指针cur= head;while(cur!=null){if(cur.random!=null)cur.next.random=cur.random.next;else cur.next.random=null;cur=cur.next.next;}//拆开,并且还原原来的链表cur = head;Node newHead = head.next;Node nxt = head.next;while(cur!=null){nxt = cur.next;cur.next = cur.next.next;if(nxt.next!=null)nxt.next = nxt.next.next;//这里是一个坑,这边实际上向后移动了两个位置,但是next已经提前断开接好了cur=cur.next;}return newHead;}
}

36 二叉搜索树与双向链表

题目

代码

在这里插入代码片

37 序列化二叉树

题目

代码

在这里插入代码片

38 字符串的排列

题目

代码

在这里插入代码片

39 数组中出现超过一半的数字

题目

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。

代码

class Solution {public int majorityElement(int[] nums) {if(nums.length==1)return nums[0];int ans = nums[0];int count = 0;for(int i =0;i<nums.length;i++){if(count==0)ans= nums[i];if(nums[i]==ans)count++;elsecount--;}return ans;}
}

40 最小的K个数

题目

输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。

代码

class Solution {public int[] getLeastNumbers(int[] arr, int k) {Queue<Integer> queue = new PriorityQueue<>();int []res =new int [k];for(int i=0;i<k;i++){queue.add(-arr[i]);}for(int i=k;i<arr.length;i++){queue.offer(-arr[i]);queue.poll();}for(int i=0;i<k;i++){res[i]=-queue.poll();}return res;}
}class Solution {//前面那就是正负交换后 最大的k个 就是原来最小的//这个思路就是直接一点,用大顶堆public int[] getLeastNumbers(int[] arr, int k) {int []res =new int [k];if(k==0)return res;Queue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>(){@Overridepublic int compare(Integer l1,Integer l2){return l2-l1;}});for(int i=0;i<k;i++){queue.add(arr[i]);}for(int i=k;i<arr.length;i++){if(arr[i]<queue.peek()){queue.poll();queue.offer(arr[i]);}}for(int i=0;i<k;i++){res[i]=queue.poll();}return res;}
}

41 数据流中的中位数

题目

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。
例如,
[2,3,4] 的中位数是 3
[2,3] 的中位数是 (2 + 3) / 2 = 2.5
设计一个支持以下两种操作的数据结构:
void addNum(int num) - 从数据流中添加一个整数到数据结构中。
double findMedian() - 返回目前所有元素的中位数

代码

class MedianFinder {/** initialize your data structure here. *///这里如何转换小顶堆 变为大顶堆要更熟练一下public Queue<Integer> MaxHeap = new PriorityQueue<Integer>(new Comparator<Integer>(){@Overridepublic int compare(Integer l1,Integer l2){return l2-l1;}});public Queue<Integer> MinHeap = new PriorityQueue<Integer>();public MedianFinder() {}public void addNum(int num) {if(MaxHeap.size()==MinHeap.size()){//这里有一个小坑peek之前要判断是否有元素的if(MinHeap.size()!=0&&num>=MinHeap.peek()){MaxHeap.offer(MinHeap.poll());MinHeap.offer(num);}else{MaxHeap.offer(num);}}else{if(num>=MaxHeap.peek()){MinHeap.offer(num);}else{MinHeap.offer(MaxHeap.poll());MaxHeap.offer(num);}}}public double findMedian() {if(MaxHeap.size()==MinHeap.size())return (MaxHeap.peek()+MinHeap.peek())/2.0;if(MaxHeap.size()>MinHeap.size())return MaxHeap.peek();return MinHeap.peek();}
}/*** Your MedianFinder object will be instantiated and called as such:* MedianFinder obj = new MedianFinder();* obj.addNum(num);* double param_2 = obj.findMedian();*/

42 连续子数组的最大和

题目

输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。
要求时间复杂度为O(n)。

代码

class Solution {public int maxSubArray(int[] nums) {if(nums.length==0)return 0;int max = nums[0],maxToCur = nums[0];for(int i =1;i<nums.length;i++){if(maxToCur<0)maxToCur=nums[i];elsemaxToCur+=nums[i];max=Math.max(max,maxToCur);}return max;}
}

43 1-n中1 出现的次数

题目

代码

在这里插入代码片

44 数字序列中某一位的数字

题目

数字以0123456789101112131415…的格式序列化到一个字符序列中。在这个序列中,第5位(从下标0开始计数)是5,第13位是1,第19位是4,等等。
请写一个函数,求任意第n位对应的数字。

代码

class Solution {//溢出问题卡了好久public int findNthDigit(int n) {int digit = 1;if(n==0)return 0;long numCount = 1;while(n-9*digit*numCount>0){n=n-(int)9*digit*(int)numCount;digit++;numCount*=10;//System.out.print(numCount+" ");}int number = n/digit;int extr = n%digit;long preNumber = numCount-1+number;if(extr==0){return (int)preNumber%10;}long nextNumber = preNumber+1;return (int)(nextNumber/((int)Math.pow(10,digit-extr)))%10;}
}

45 把数组排成最小的数

题目

输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。

代码

class Solution {public String minNumber(int[] nums) {String[] num = new String[nums.length];for(int i =0;i<nums.length;i++){num[i]=String.valueOf(nums[i]);}//这里还是重写comparator的方法比较习惯Arrays.sort(num,new Comparator<String>(){@Overridepublic int compare(String l1,String l2){return (l1+l2).compareTo(l2+l1);}});StringBuilder str = new StringBuilder();for(int i =0;i<num.length;i++){str.append(num[i]);}return str.toString();}
}

46 把数字翻译成字符串

题目

给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。

代码

class Solution {//来一个全局的计数器public int count = 0;public int translateNum(int num) {String nums = String.valueOf(num);int size =nums.length();if(size==1)return 1;//递归的用字符串搞定search(nums);return count;}public void search(String nums){int size = nums.length();//遍历到最后一位 就是一种情况完成了if(nums.length()==1){count++;return ;}//在每个大于等于2的情境下,都可以考虑变换一位和两位一起变化两种情况if(nums.charAt(0)=='1'||nums.charAt(0)=='2'&&nums.charAt(1)<='5'){search(nums.substring(1,nums.length()));//这里注意一下 substring是不给出空字符的情况,所以2个长度的substring(2)是报错的这里直接加即可if(nums.length()>2)search(nums.substring(2,nums.length()));elsecount++;}elsesearch(nums.substring(1,nums.length()));}
}

47 礼物的最大价值

题目

在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?

代码

class Solution {public int maxValue(int[][] grid) {int m =grid.length;int n =grid[0].length;for(int i=1;i<n;i++)grid[0][i]=grid[0][i]+grid[0][i-1];for(int i=1;i<m;i++)for(int j=0;j<n;j++)if(j==0)grid[i][j]=grid[i-1][j]+grid[i][j];elsegrid[i][j]=Math.max(grid[i-1][j],grid[i][j-1])+grid[i][j];return grid[m-1][n-1];}
}

48 最长不含重复字符的子串

题目

最长不含重复字符的子字符串

代码

class Solution {public int lengthOfLongestSubstring(String s) {boolean flagOfchar[]= new boolean[128];int len=0;int left = 0,right =0;while(right<s.length()){if(!flagOfchar[s.charAt(right)]){flagOfchar[s.charAt(right)]=true;right++;}else{len = Math.max(len,right-left);while(!flagOfchar[s.charAt(left)]){left++;}flagOfchar[s.charAt(left)]=false;left++;}}//right++直接跳出循环的情况,可能更新办不到len,所以在这个地方补充更新一下len = Math.max(len,right-left);return len;}
}

49 丑数

题目

我们把只包含质因子 2、3 和 5 的数称作丑数(Ugly Number)。求按从小到大的顺序的第 n 个丑数。

代码

class Solution {public int nthUglyNumber(int n) {int [] UglyNumber= new int[n];UglyNumber[0]=1;int NumberOfTwo=0;int NumberOfThree = 0;int NumberOfFive = 0;for(int i=1;i<n;i++){int next=UglyNumber[NumberOfTwo]*2;if(next>UglyNumber[NumberOfThree]*3)next=UglyNumber[NumberOfThree]*3;if(next>UglyNumber[NumberOfFive]*5)next=UglyNumber[NumberOfFive]*5;if(next==UglyNumber[NumberOfTwo]*2)NumberOfTwo++;if(next==UglyNumber[NumberOfThree]*3)NumberOfThree++;if(next==UglyNumber[NumberOfFive]*5)NumberOfFive++;UglyNumber[i]=next;}return UglyNumber[n-1];}
}

50 第一个只出现一次的字符

题目

在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。 s 只包含小写字母。

代码

class Solution {public char firstUniqChar(String s) {if(s.length()==0)return ' ';int [] charNum = new int[26];for(int i =0;i<s.length();i++){charNum[s.charAt(i)-'a']++;}for(int i =0;i<s.length();i++){if(charNum[s.charAt(i)-'a']==1){return s.charAt(i);}}return ' ';}
}

51 数组中的逆序对数组中的逆序对

题目

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。

代码

class Solution {public int reversePairs(int[] nums) {int[] temp = new int[nums.length];return mergeSort(nums, 0, nums.length-1, temp);}//如果还有两个以上元素就划分,划分完合并 ,并且记录左边的计数+右边计数+自己计数public int mergeSort(int []nums,int left,int right,int []temp){if(left<right){int mid = (left+right)/2;int leftCount = mergeSort(nums,left,mid,temp);int rightCount = mergeSort(nums,mid+1,right,temp);int mergeCount = mergeArray(nums,left,mid,right,temp);return leftCount+rightCount+mergeCount;}else{return 0;}}//用一个temp数组做中间转存,避免中途频繁创建,中转后将数组对应位置赋值回num数组public int mergeArray(int []nums,int left,int mid,int right,int[]temp){int count = 0;int leftIndex= left,rightIndex= mid+1;for(int i =left;i<=right;i++){if(leftIndex>mid){temp[i]=nums[rightIndex++];continue;}if(rightIndex>right){temp[i]=nums[leftIndex++];continue;}if(nums[leftIndex]<=nums[rightIndex]){temp[i]=nums[leftIndex++];}else{temp[i]=nums[rightIndex++];//这里是计数的关键,每次逆序就将左面的数字个数加上去//因为递增的,最左逆序肯定都是逆序count=count+mid-leftIndex+1;}}for(int i=left;i<=right;i++){nums[i]=temp[i];}return count;}
}

52 两个链表的第一个公共节点

题目

输入两个链表,找出它们的第一个公共节点。

代码

/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode(int x) {*         val = x;*         next = null;*     }* }*/
public class Solution {public ListNode getIntersectionNode(ListNode headA, ListNode headB) {if(headA==null||headB==null)return null;ListNode curA=headA,curB=headB;//这里的顺序很重要//要及时将null移动到链表头//并且可以通过两者都为null判断他们确实没有while(curA!=curB){curA=curA.next;curB=curB.next;if(curA==null&&curB==null)return null;if(curA==null){curA=headB;}if(curB==null){curB=headA;}}return curA;}
}

53 在排序数组中查找数字

题目

统计一个数字在排序数组中出现的次数。

代码

class Solution {public int search(int[] nums, int target) {int left = 0,right = nums.length-1;if(nums.length==0)return 0;while(left+1<right){int mid = (left+right)/2;if(nums[mid]>target||nums[mid]==target&&mid-1>=left&&nums[mid-1]==target)right =mid;elseleft=mid;}int leftIndex= 0,rightIndex=0;if(nums[left]==target)leftIndex= left;elseleftIndex=right;//上面找到最左索引位置, 下面找到最右索引位置,都是用二分法left = 0;right = nums.length-1;while(left+1<right){int mid = (left+right)/2;if(nums[mid]<target||nums[mid]==target&&mid+1<=right&&nums[mid+1]==target)left =mid;elseright=mid;}if(nums[right]==target)rightIndex= right;elserightIndex= left;//存在一种找不到的情况,索引不会被更新if(rightIndex==0&&leftIndex==0)if(nums[0]!=target)return 0;return rightIndex-leftIndex+1;}
}

54 0到n-1中的缺失数字

题目

一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。

代码

class Solution {public int missingNumber(int[] nums) {//这个题原本使用了On的觉得不错,实际上因为是升序//所以可以优化为二分法,比较隐蔽int left = 0,right = nums.length;int mid = 0;while(left+1<right){mid = left+(right-left)/2;if(nums[mid]==mid)left = mid;elseright = mid;}if(nums[left]==left)return right;elsereturn left;}
}

55 二叉搜索树第K大的节点值

题目

给定一棵二叉搜索树,请找出其中第k大的节点。

代码

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode(int x) { val = x; }* }*/
class Solution {int k;int val=0;//一个全局的K控制遍历的个数, val用于返回public int kthLargest(TreeNode root, int k) {this.k=k;search(root);return val;}//实现一个右根左的遍历顺序 顺序就是由大到小public void search(TreeNode root){if(root.right!=null)search(root.right);k--;if(k==0)val= root.val;if(root.left!=null)search(root.left);}
}

56 二叉树的深度

题目

输入一棵二叉树的根节点,求该树的深度。从根节点到叶节点依次经过的节点(含根、叶节点)形成树的一条路径,最长路径的长度为树的深度

代码

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode(int x) { val = x; }* }*/
class Solution {//舒服的一行搞定,有点刻意了//核心在于将最后的结果 统一到空节点一起处理,空为0public int maxDepth(TreeNode root) {return root==null?0:Math.max(maxDepth(root.right),maxDepth(root.left))+1;}
}

57 平衡二叉树

题目

输入一棵二叉树的根节点,判断该树是不是平衡二叉树。如果某二叉树中任意节点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树

代码

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode(int x) { val = x; }* }*/
class Solution {//逻辑要清洗,平衡的条件是自己平衡且左右子树都平衡//然后如何判断自己平衡,就是通过左右子树的深度差不超过1//相当于两个递归问题public boolean isBalanced(TreeNode root) {if(root==null)return true;if(root.left==null&&root.right ==null)return true;if(Math.abs(depth(root.left)-depth(root.right))<=1){return isBalanced(root.right)&&isBalanced(root.left);}return false;}public int depth(TreeNode root){if(root==null)return 0;return Math.max(depth(root.right),depth(root.left))+1;}
}

58 数组中数字出现的次数I

题目

一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。

代码

class Solution {//思路清晰,锻炼一下实现能力//先异或,找到两个不同的数异或为1的位置//依据这个位置为0 还是为 1 划分为两个数组,再异或就分别得到两个结果public int[] singleNumbers(int[] nums) {List<Integer> numberOfOne = new ArrayList<>();List<Integer> numberOfZero = new ArrayList<>();int divide = nums[0];for(int i = 1;i<nums.length;i++)divide=divide^nums[i];int bit = 1;while((divide&bit)==0)bit =bit<<1;for(int i=0;i<nums.length;i++)if((bit&nums[i])!=0)numberOfOne.add(nums[i]);elsenumberOfZero.add(nums[i]);int []res = new int[2];res[0]=numberOfZero.get(0);res[1]=numberOfOne.get(0);for(int i =1;i<numberOfOne.size();i++)res[1]=res[1]^numberOfOne.get(i);for(int i = 1;i<numberOfZero.size();i++)res[0]=res[0]^numberOfZero.get(i);return res;}
}

59 数组中数字出现的次数II

题目

在一个数组 nums 中除一个数字只出现一次之外,其他数字都出现了三次。请找出那个只出现一次的数字。

代码

class Solution {//感觉思路还可以 就是很慢//出现三次,那就二进制加法,对每一位的数求和,然后对3取余,剩下的就是那个唯一的数。public int singleNumber(int[] nums) {int [] bitArray = new int [32];for(int i =0;i<nums.length;i++){int bit= 0;while(nums[i]>=(1<<bit)&&bit<32){if((nums[i]&(1<<bit))!=0){bitArray[bit]++;}bit++;}}for(int i=0;i<32;i++){bitArray[i]=bitArray[i]%3;}int ans = 0;for(int i=0;i<32;i++){if(bitArray[i]!=0){ans=ans+(1<<i);}}return ans;}
}

60 和位S的两个数字

题目

输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。

代码

class Solution {public int[] twoSum(int[] nums, int target) {int left = 0,right = nums.length-1;int [] res = new int[2];while(left<right){if(nums[left]==target-nums[right]){res[0]=nums[left];res[1]=nums[right];return res;}if(nums[left]<target-nums[right])left++;elseright--;}return res;}
}

61 和位S的连续正数序列

题目

输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。
序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。

代码

class Solution {public int[][] findContinuousSequence(int target) {ArrayList<ArrayList<Integer>> res = new ArrayList<>();ArrayList<Integer> temp= new ArrayList<>();int left = 1,sum = 0;for(int i =1;i<=target/2+2;i++){if(sum>target){sum-=left;temp.remove(0);left++;i--;continue;}if (sum == target)res.add((ArrayList<Integer>)temp.clone());sum+=i;temp.add(i);}int [][]finalAns = new int [res.size()][];for(int i =0;i<res.size();i++){finalAns[i]= new int [res.get(i).size()];for(int j=0;j<finalAns[i].length;j++){finalAns[i][j]=res.get(i).get(j);}}return finalAns;}
}

62 翻转单词顺序

题目

输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。为简单起见,标点符号和普通字母一样处理。例如输入字符串"I am a student. “,则输出"student. a am I”。

代码

class Solution {public String reverseWords(String s) {//使用了StringBuffer的reverse,String 类的substringStringBuffer res= new StringBuffer();for(int i=0;i<s.length();i++){while(i<s.length()&&s.charAt(i)==' ')i++;int j=i;if(i==s.length())break;while(j<s.length()&&s.charAt(j)!=' ')j++;res.append(new StringBuffer(s.substring(i,j)).reverse().toString()+' ');i=j;}if(res.length()==0)return "";return res.reverse().toString().substring(1);}
}

63 左旋转字符串

题目

字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。

代码

class Solution {// StringBuffer可以替换res=“”这个方法,更高效一点public String reverseLeftWords(String s, int n) {if(n>=s.length())return s;StringBuffer res = new StringBuffer();res.append(s.substring(n));res.append(s.substring(0,n));return res.toString();}
}

64 滑动窗口的最大值

题目

给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。

代码

class Solution {//双端队列是一个不太熟悉的数据结构//单调队列的思路,核心思想在于 x入队之后x之前比x小的就没有用了//滑动窗口移动的时候,如果队列头是这个元素,也要一起移出去//所以x移出滑动窗口的时候 队列中x前面的元素肯定已经不再队列了  要么被覆盖 要么自己移出了Deque<Integer> queue = new LinkedList<>();public int[] maxSlidingWindow(int[] nums, int k) {if(nums.length==0)return new int[0];int [] res = new int[nums.length-k+1];for(int i =0;i<k;i++){while(queue.size()>0&&nums[i]>queue.getLast())queue.removeLast();queue.offerLast(nums[i]);}res[0]=queue.getFirst();int index =1;for(int i=k;i<nums.length;i++){//这是覆盖过程while(queue.size()>0&&nums[i]>queue.getLast())queue.removeLast();queue.offerLast(nums[i]);//这是主动移出的过程if(queue.getFirst()==nums[i-k])queue.removeFirst();res[index++]=queue.getFirst();}return res;}
}

65 队列的最大值

题目

请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_value、push_back 和 pop_front 的均摊时间复杂度都是O(1)。

若队列为空,pop_front 和 max_value 需要返回 -1

代码

class MaxQueue {//双端队列维护一个单调队列 还是基于覆盖元素的思想直接删除部分无价值的元素Deque<Integer> deque = new LinkedList<>();Queue<Integer>queue = new LinkedList<>();public MaxQueue() {}public int max_value() {if(deque.size()==0)return -1;return deque.getFirst();}public void push_back(int value) {queue.offer(value);while(deque.size()>0&&value>deque.getLast())deque.removeLast();deque.offerLast(value);}public int pop_front() {if(queue.size()==0)return -1;int num = queue.poll();if(num == deque.getFirst()){deque.removeFirst();}return num;}
}/*** Your MaxQueue object will be instantiated and called as such:* MaxQueue obj = new MaxQueue();* int param_1 = obj.max_value();* obj.push_back(value);* int param_3 = obj.pop_front();*/

66 n个骰子的点数

题目

把n个骰子扔在地上,所有骰子朝上一面的点数之和为s。输入n,打印出s的所有可能的值出现的概率。
你需要用一个浮点数数组返回答案,其中第 i 个元素代表这 n 个骰子所能掷出的点数集合中第 i 小的那个的概率。

代码

class Solution {int [] count ;//通过一个额外数组记录点数出现的次数//实际上通过循环似乎也可以完成public double[] twoSum(int n) {count = new int[6*n+1];computeSum(n,0);double []res = new double [5*n+1];for(int i =0;i<res.length;i++)res[i]=count[i+n]/Math.pow(6,n);return res;}public void computeSum(int n,int sum){if(n ==0){count[sum]++;return ;}for(int i=1;i<=6;i++){sum+=i;computeSum(n-1,sum);sum-=i;}}
}

67 扑克牌中的顺子

题目

从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为 0 ,可以看成任意数字。A 不能视为 14。、

代码

class Solution {public boolean isStraight(int[] nums) {Arrays.sort(nums);//记录一下大小王的个数int chance=0;boolean flag=false;int expect = 0;for(int i =0;i<5;i++){if(nums[i]==0){chance++;continue;}if(flag==false&&nums[i]!=0){expect = nums[i]+1;flag=true;continue;}if(flag ==true){if(nums[i]<expect)return false;if(chance>=nums[i]-expect){chance = chance-nums[i]+expect;expect=nums[i]+1;}elsereturn false;}}return true;}
}

68 圆圈中最后剩下的数字

题目

0,1,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。

例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。

代码

class Solution {//约瑟夫问题//首先 把问题看做胜利者在数组中的索引变化  每一轮 index-m  假设第N轮知道胜利者为6 第N-1轮是3//反推 最后胜利者的索引为0   回推一轮 就是 +m  避免越界 对size取余。public int lastRemaining(int n, int m) {int p = 0;int ans = 0;for(int i =2;i<=n;i++){ans = (ans+m)%i;}return ans;}
}

69 股票的最大利润

题目

假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖该股票一次可能获得的最大利润是多少?

代码

class Solution {//注意这个只能买一次啊  所以要记录一下当前最小值public int maxProfit(int[] prices) {int max= 0;if(prices.length==0)return 0;int min= prices[0];for(int i = 1;i<prices.length;i++){if(prices[i]<min)min = prices[i];max = Math.max(max,prices[i]-min);}return max;}
}

70 求1+2+…+n

题目

求 1+2+…+n ,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)

代码

class Solution {//妙啊  使用了短路原理public int sumNums(int n) {int sum=n;boolean flag= n>0&&(sum+=sumNums(n-1))>0;return sum;}
}

71 不用加减做加法

题目

写一个函数,求两个整数之和,要求在函数体内不得使用 “+”、“-”、“*”、“/” 四则运算符号。

代码

class Solution {//这个正负不需要判断 确实有点巧妙  也是补码的优势public int add(int a, int b) {int c = a^b;int d = (a&b)<<1;while(d!=0){int tempc = c;c = tempc^d;d=(tempc&d)<<1;}return c;}
}

72 构建乘积数组

题目

给定一个数组 A[0,1,…,n-1],请构建一个数组 B[0,1,…,n-1],其中 B 中的元素 B[i]=A[0]×A[1]×…×A[i-1]×A[i+1]×…×A[n-1]。不能使用除法。

代码

class Solution {//增加两个数组记录不包括自己的 左侧的乘积 和右侧的乘积//最后左面乘右面结束public int[] constructArr(int[] a) {if(a.length==0)return a;int []left = new int[a.length];int []right = new int[a.length];left[0]=1;right[a.length-1]=1;for(int i=1;i<a.length;i++)left[i]=left[i-1]*a[i-1];for(int i=a.length-2;i>=0;i--)right[i]=right[i+1]*a[i+1];for(int i = 0;i<a.length;i++)a[i]=left[i]*right[i];return a;}
}

73 字符串转换成整数

题目

代码

在这里插入代码片

74 二叉搜索树的最近公共祖先

题目

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

代码

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode(int x) { val = x; }* }*/
class Solution {//归功于二叉搜索树  就是从上到下找到第一个 处于pq之间的节点 public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {//保证后面传入参数 p是小于q的,后面统一操作if(p.val<q.val)return search(root, p ,q);return search(root,q,p);}public TreeNode search(TreeNode root,TreeNode p,TreeNode q){if(root.val>=p.val&&root.val<=q.val)return root;if(root.val<p.val)return search(root.right,p,q);elsereturn search(root.left,p,q);}
}

75 二叉树的最近公共祖先(普通二叉树)

题目

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

代码

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode(int x) { val = x; }* }*/
class Solution {//这个题 就是上一个题的泛化, 普通的二叉树,需要递归查找子树中是否有pq  //查找第一个左右子树都有pq的节点  pq是否包含的情况向上传递 public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {if(root==null)return null;if(root == p||root==q)return root;TreeNode left= lowestCommonAncestor(root.left,p,q);TreeNode right= lowestCommonAncestor(root.right,p,q);if(left!=null&&right!=null) return root;return left!=null?left:right;}
}

剑指offer第二版(leetcode)Java题解(不断更新)相关推荐

  1. 剑指Offer第二版Java代码实现

    剑指Offer第二版Java代码实现 A.单例模式 面试题 2:实现Singleton模式 B.面试需要的基础知识 面试题 3:数组中重复的数字 面试题 4:二维数组的查找 面试题 5:替换空格 面试 ...

  2. python数据结构与算法刷题——剑指offer第二版加部分leetcode题

    说不清楚,只能看代码理解的用红色标出 查找算法:查找较排序来说较简单,不外乎顺序查找和二分查找.哈希表查找和二叉排序树查找.(很多面试官喜欢让应聘者写出二分查找(如test53)的代码)[注意:二分查 ...

  3. 剑指offer第二版答案详细版(带详细解题思路)

    1.滑动窗口的最大值(剑指offer原59题) 解题思路:其实是一个队列的问题,用一个队列去维护当前窗口中的所有元素:首先将超出窗口中的队头元素先删掉,然后将新的元素插入当前窗口中,插入时要判断新插入 ...

  4. 剑指offer 第二版(101——119)(全部完结)

    剑指 Offer II 101. 分割等和子集 bool canPartition(vector<int>& nums) {int sum=0;for(int i=0;i<n ...

  5. 剑指Offer——编程题的Java实现(更新完毕……)

    目录 二维数组中的查找 替换空格 从尾到头打印链表 重建二叉树 用两个栈实现队列 用两个队列实现一个栈 旋转数组的最小数字 斐波那契数列 跳台阶 变态跳台阶 矩形覆盖 二进制中1的个数 数值的整数次方 ...

  6. JAVA实现 剑指offer第二版 2

    面试题16:数值的整数次方 需要考虑底数为0的情况,指数为正或负的情况:在计算次方时,应注意到4次方为2次方的2次方,可以进行递归调用减少复杂度:也要主要到double类型的比较不能直接使用==: p ...

  7. 剑指offer第二版——面试题9(java)

    面试题9:用两个栈实现队列 题目描述:  用两个栈实现一个队列.队列的声明如下,请实现它的两个函数appendTail和deletedHead,分别完成在队列尾部插入节点和在队列头部删除节点的功能. ...

  8. 剑指offer第二版-9.用两个栈实现队列

    描述:使用两个栈实现一个队列.队列中实现尾部插入和头部删除函数. 思路:stack1负责插入,stack2负责弹出,如果stack2为空了,将stack1的元素依次弹出并存放到stack2中,之后对s ...

  9. 剑指offer第二版(150M超清分享PDF+源码)(转)

    链接:https://pan.baidu.com/s/1b6ZxVIBvjPfKifToh_h26Q 密码:6t76 https://github.com/zhedahht/ChineseCoding ...

最新文章

  1. java bio_Java BIO及实现
  2. C#读取Excel显示到repeater中
  3. pythonwhile输出每一个余数_Python 基础 - day02-3
  4. Python3中的yield from语法
  5. 美国知名DJ 3LAU以1160万美元出售全球首套音乐专辑NFT藏品
  6. 如何通过TRAMP / Emacs远程控制nrepl-ritz-jack-in工作
  7. 15 个可在 Chrome 浏览器上体验 WebGL 的例子
  8. oracle的db的容量计算公式,Oracle如何精确计算row的大小
  9. Centos 使用防火墙 Firewalld 进行流量转发
  10. .lrc 格式的歌词乱码,如何修改后正常显示
  11. iOS 点击图片放大效果
  12. ios push上移64_iOS上的C64 Basic
  13. IDEA 奇淫 插件
  14. 抖音原创视频如何制作?鹰迪电子商务
  15. 计算机发展史图,图说计算机发展史
  16. jdbc4.MySQLSyntaxErrorException: SELECT command denied to user '用户名'@'localhost' for table '表名'
  17. 【微软Visual Studio面世20周年巨制】全宇宙功能最强大IDE Visual Studio 2017 正式版发布
  18. argc,**argv
  19. 【FLACC】A Greedy Agglomerative Framework for Clustered Federated Learning
  20. web前端开发笔试题

热门文章

  1. TwinCAT隐藏开机画面
  2. 只读事务是否做无用功?
  3. 爆聚美优品售假货,中国老龄商城有话说
  4. codeforces1000a csdn-博客
  5. 51Nod-1000A+B
  6. 国内食品品牌策划公司排名,食品品牌设计公司哪家好?2021最新
  7. 【TensorFlow学习笔记】完美解决 pip3 install tensorflow 没有models库,读取PTB数据
  8. Java是剑客-飘逸;.NET是刀客-霸道 (一)
  9. jupyter输出为html隐藏代码,在jupyter noteb中隐藏代码
  10. rancher 企业级容器管理平台