Java热题100(简单 中等题) 持续更新

1、两数之和   

  public int[] twoSum(int[] nums, int target) {
        int [] result=new int[2];
        HashMap map=new HashMap<Integer,Integer>();
        for(int i=0;i<nums.length;i++){
            if(!map.containsKey(target-nums[i])){
                map.put(nums[i],i);
            }else{            
                result[0]=(int)map.get(target-nums[i]);
                result[1]=i;
            }
        }
        return result;
    }

containsKey 

2、 字母异位词分组 

 public List<List<String>> groupAnagrams(String[] strs) {
        List<List<String>> result = new ArrayList<>();
        HashMap<String, List<String>> map = new HashMap<>();
        for (int i = 0; i < strs.length; i++) {
            char[] chars = strs[i].toCharArray();
            Arrays.sort(chars);
            String key = new String(chars);
            if (!map.containsKey(key)) {
                List<String> list = new ArrayList();
                list.add(strs[i]);
                map.put(key, list);
            } else {
                List<String> addList = map.get(key);
                addList.add(strs[i]);
            }
        }
        for (Object o : map.keySet()) {
            result.add(map.get(o));
        }
        return result;

    }

new String(); 创建list集合、map集合等 

3、最长连续序列

HashSet<Integer> set = new HashSet<>();
        int res = 0;
        for (int num : nums) {
            set.add(num);
        }
        for (int i = 0; i < nums.length; i++) {
            if (!set.contains(nums[i] - 1)) {
                int curNum = nums[i];
                int curLen = 1;
                while (set.contains(curNum + 1)) {
                    curNum = curNum + 1;
                    curLen = curLen + 1;
                }
                res = Math.max(res, curLen);
            }
        }
        return res;

4、移动零

public void moveZeroes(int[] nums) {
        int left = 0;
        if (nums.length == 0 || nums.length == 1) return;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] != 0) {
                int temp = nums[i];
                nums[i] = nums[left];
                nums[left] = temp;
                left++;
            }
        }
    }

5、盛最多少的容器

 public int maxArea(int[] height) {
        int left=0;
        int right=height.length-1;
        int vol=0;
        int result=0;
        while(left<right){
            if(height[left]>height[right]){
                vol=(right-left)*height[right];
                right--;
            }else{
                vol=(right-left)*height[left];
                left++;
            }
            result=result>vol?result:vol;
        }
        return result;
    }

6、三数之和

public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> res=new ArrayList<>();
        Arrays.sort(nums);

        if(nums.length<3){
            return res;
        }
        for(int i=0;i<nums.length-2;i++){  
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue; // 跳过重复元素
            }
            int left=i+1;
            int right=nums.length-1;  
            while(left<right){
                if(nums[i]+nums[left]+nums[right]==0){
                    List<Integer> midList=new ArrayList<>();
                    midList.add(nums[i]);
                    midList.add(nums[left]);
                    midList.add(nums[right]);
                    res.add(midList);
                    while (left < right && nums[left] == nums[left + 1]) {
                        left++; // 跳过重复元素
                    }
                    while (left < right && nums[right] == nums[right - 1]) {
                        right--; // 跳过重复元素
                    }
                    right--;
                    left++;
                }else if(nums[i]+nums[left]+nums[right]>0){
                    right--;
                }else{
                    left++;
                }
            }
        }
        return res;
    }

7、除自身以外数组的乘积

public int[] productExceptSelf(int[] nums) {
        int n=nums.length;
        int[] res=new int[n];
        int[] right=new int[n];
        right[n-1]=1;
        int[] left=new int[n];
        left[0]=1;
        for(int i=1;i<n;i++){
            left[i]=left[i-1]*nums[i-1]; 
        }
        for(int i=n-2;i>=0;i--){
            right[i]=right[i+1]*nums[i+1];
        }
        for(int i=0;i<n;i++){
            res[i]=left[i]*right[i];
        }
        return res;
    }

 8、轮转数组

    public void rotate(int[] nums, int k) {
        if(k==nums.length) return;
        resverse(nums,0,nums.length-1);
        resverse(nums,0,(k-1)%nums.length);
        resverse(nums,(k)%nums.length,nums.length-1);
    }
    public void resverse(int[] nums,int begin,int end){
        while(begin<end){
        int temp=nums[end]; 
        nums[end]=nums[begin];
        nums[begin]=temp;
        begin++;
        end--;
       }
    }

9、合并区间

 public int[][] merge(int[][] intervals) {
        Arrays.sort(intervals,(int[] o1,int[] o2)->o1[0]-o2[0]);
        LinkedList<int []> list=new LinkedList<>();
        list.add(intervals[0]);
        for(int i=1;i<intervals.length;i++){
            int[] last=list.getLast();
            if(intervals[i][0]<=last[1]){
                last[1]=Math.max(intervals[i][1],last[1]);
            }else{
                list.add(intervals[i]);
            }
        }
        return list.toArray(new int[0][0]);
    }

10、最大子数组和

public int maxSubArray(int[] nums) {
        int res=0;
        int[] maxSum =new int[nums.length];
        maxSum[0]=nums[0];
        for(int i=1;i<nums.length;i++){
           if(maxSum[i-1]>0){
            maxSum[i]=maxSum[i-1]+nums[i];
           }else{
            maxSum[i]=nums[i];
           }
        }
        Arrays.sort(maxSum);
        return maxSum[nums.length-1];
    }

11、矩阵置零

public void setZeroes(int[][] matrix) {
        boolean[] row=new boolean[matrix.length];
        boolean[] col=new boolean[matrix[0].length];
        for(int i=0;i<matrix.length;i++){
            for(int j=0;j<matrix[0].length;j++){
                if(matrix[i][j]==0){
                    row[i]=true;
                    col[j]=true;
                }
            }
        }
        for(int i=0;i<matrix.length;i++){
            for(int j=0;j<matrix[0].length;j++){
                if(row[i]||col[j]){
                    matrix[i][j]=0;
                }
            }
        }
    }

12、螺旋矩阵

public List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> list=new ArrayList<>();
        int row=matrix.length;
        int col=matrix[0].length;
        int left=0;
        int right=col-1;
        int up=0;
        int down=row-1;
        while(list.size()<row*col){
            if(up<=down){
                for(int j=left;j<=right;j++){
                    list.add(matrix[up][j]);
                }
                up++;
            }
            if(left<=right){
                for(int j=up;j<=down;j++){
                    list.add(matrix[j][right]);
                }
                right--;
            }
            if(up<=down){
                for(int j=right;j>=left;j--){
                    list.add(matrix[down][j]);
                }
                down--;
            }
            if(left<=right){
                for(int j=down;j>=up;j--){
                    list.add(matrix[j][left]);
                }
                left++;
            }
        }
        return list;
    }

13、旋转图像

class Solution {
    public void rotate(int[][] matrix) {
        int m=matrix.length;
        for(int i=0;i<m;i++){
            for(int j=i;j<m;j++){
                int temp=matrix[i][j];
                matrix[i][j]=matrix[j][i];
                matrix[j][i]=temp;
            }
        }
        for(int i=0;i<m;i++){
            reserve(matrix[i],0,matrix[0].length-1);
        }
    }
    public void reserve(int[] nums,int begin,int end){
        while(begin<end){
            int temp=nums[begin];
            nums[begin]=nums[end];
            nums[end]=temp;
            begin++;
            end--;
        }
    }
}

14、搜索二维矩阵

public boolean searchMatrix(int[][] matrix, int target) {
        boolean res=false;
        int m=matrix.length;
        int n=matrix[0].length;
        for(int i=0;i<m;i++){
            for(int j=0;j<n;){
                if(target==matrix[i][j]){
                    res=true;
                    return res;
                }
                if(target<matrix[i][j]){
                    break;
                }
                if(target>matrix[i][j]){
                    j++;
                }
                
            }
        }
        return res;
    }

15、无重复字符的最长字串

public int lengthOfLongestSubstring(String s) {
        int left = 0;
        int right = 0;
        int res = 0;
        HashMap<Character, Integer> map = new HashMap<>();
        while (right < s.length()) {
            char c = s.charAt(right);
            right++;
            map.put(c, map.getOrDefault(c, 0) + 1);
            while (map.get(c) > 1) {
                char m = s.charAt(left);
                left++;
                map.put(m, map.get(m) - 1);
            }
            res = Math.max(res, right - left);
        }
        return res;
    }

16、找到字符串中的所有字母异位词

public List<Integer> findAnagrams(String s, String p) {
        List<Integer> list=new ArrayList<>();
        int left=0;
        int right=0;
        int vaild=0;
        HashMap <Character,Integer> p_map=new HashMap<>();
        HashMap <Character,Integer> s_map=new HashMap<>();
        for(int i=0;i<p.length();i++){
            p_map.put(p.charAt(i),p_map.getOrDefault(p.charAt(i),0)+1);
        }
        while(right<s.length()){
            char c=s.charAt(right);
            right++;
            if(p_map.containsKey(c)){
                s_map.put(c,s_map.getOrDefault(c,0)+1);
                if(s_map.get(c).equals(p_map.get(c))){
                    vaild++;
                }
            }
            while(right-left>=p.length()){
                if(vaild==p_map.size())
                    list.add(left);
                char m=s.charAt(left);
                left++;
                if(p_map.containsKey(m)){
                    if(s_map.get(m).equals(p_map.get(m))){
                        vaild--;
                    }
                    s_map.put(m,s_map.get(m)-1);
                }              
            }            
        }
        return list;
    }

17、和为K的子数组

public int subarraySum(int[] nums, int k) {
    int res = 0;
    int sum = 0;
    HashMap<Integer, Integer> sumMap = new HashMap<>();
    sumMap.put(0, 1);  
    for (int num : nums) {
        sum += num;
        if (sumMap.containsKey(sum - k)) {//sum-k代表从不同起点到当前点的子数组和为k的不同情况
            res += sumMap.get(sum - k);
        }
        sumMap.put(sum, sumMap.getOrDefault(sum, 0) + 1);
    }
    return res;
}

18、最小覆盖子串

public String minWindow(String s, String t) {
        int left=0;
        int right=0;
        int valid=0;
        HashMap<Character, Integer> t_map=new HashMap<>();
        HashMap<Character, Integer> s_map=new HashMap<>();
        for(int i=0;i<t.length();i++) {
            t_map.put(t.charAt(i),t_map.getOrDefault(t.charAt(i),0)+1);
        }
        int start=0;
        int len=Integer.MAX_VALUE;
        while(right<s.length()){
            char c=s.charAt(right);
            if(t_map.containsKey(c)){
                s_map.put(c,s_map.getOrDefault(c,0)+1);
                    if(s_map.get(c).equals(t_map.get(c)))  {
                        valid++;
                    }
            }
            right++;
            while(valid==t_map.size()){
                if(right-left<len){
                    start=left;
                    len=right-left;
                }
                char m=s.charAt(left);
                if(t_map.containsKey(m)){
                    if(s_map.get(m).equals(t_map.get(m)))  {
                        valid--;
                    }
                    s_map.put(m,s_map.get(m)-1);
                }
                left++;
            }
        }
        return len==Integer.MAX_VALUE?"":s.substring(start,start+len);
    }

19、相交链表

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode s1=headA;
        ListNode s2=headB;
        Set<ListNode> set=new HashSet<>();
        while(s1!=null){
            set.add(s1);
            s1=s1.next;
        }
        while(s2!=null){
            if(set.contains(s2)){
                return s2;
            }
            s2=s2.next;
        }
        return null;    
    }

20、反转链表

public ListNode reverseList(ListNode head) {
        ListNode pre=null;
        ListNode cur=head;
        while(cur!=null){
            ListNode temp=cur.next;
            cur.next=pre;
            pre=cur;
            cur=temp;
        }
        return pre;
    }

21、回文链表

public boolean isPalindrome(ListNode head) {
        ListNode cur=head;
        List<Integer> list=new ArrayList<>();
        while(cur!=null){
            list.add(cur.val);
            cur=cur.next;
        }
        int left=0;
        int right=list.size()-1;
        while(left<right){
            if(list.get(left)!=list.get(right)){
                return false;
            }
            left++;
            right--;
        }
        return true;
    }

22、环形链表

public boolean hasCycle(ListNode head) {
        Set<ListNode> set=new HashSet<>();
        ListNode cur=head;
        while(cur!=null){
            if(set.contains(cur)){
                return true;
            }else{
            set.add(cur);
            }
            cur=cur.next;
        }
        return false;
    }

23、环形链表2

public ListNode detectCycle(ListNode head) {
        Set<ListNode> set=new HashSet<>();
        ListNode cur=head;
        while(cur!=null){
            if(set.contains(cur)){
                return cur;
            }else{
            set.add(cur);
            }
            cur=cur.next;
        }
        return null;
    }

24、合并两个有序链表

public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        ListNode head1=list1;
        ListNode head2=list2;
        ListNode newHead=new ListNode();
        ListNode result=newHead;
        while(head1!=null && head2!=null){
            if(head1.val<=head2.val){
                newHead.next=head1;
                head1=head1.next;
                newHead=newHead.next;
            }else{
                newHead.next=head2;
                head2=head2.next;
                newHead=newHead.next;
            }    
        }
        if(head1==null){
            newHead.next=head2;
        }else if(head2==null){
            newHead.next=head1;
        }
        return result.next;
    }

25、两数相加

public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode head1=l1;
        ListNode head2=l2;
        ListNode newHead=new ListNode();
        ListNode cur=newHead;
        int forward=0;
        int curVal=0;
        while(head1!=null || head2!=null){
            int x=head1==null?0:head1.val;
            int y=head2==null?0:head2.val;
            int sum=x+y+forward;
            forward=sum/10;
            curVal=sum%10;
            cur.next=new ListNode(curVal);
            cur=cur.next;
            if(head1!=null){
                head1=head1.next;
            }
            if(head2!=null){
                head2=head2.next;
            }
        }
        if(forward!=0){
            cur.next=new ListNode(forward);
        }
        return newHead.next;
    }

26、删除链表的倒数第N个结点

public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode pre=new ListNode();
        pre.next=head;
        ListNode fast=pre;
        ListNode slow=pre;
        for(int i=0;i<=n;i++){
            fast=fast.next;
        } //快指针先走n+1步
        while(fast!=null){
            fast=fast.next;
            slow=slow.next;
        }//快慢指针同时走,直到快指针走到null
        slow.next=slow.next.next;
        return pre.next;
}

27、两两交换链表中的节点

public ListNode swapPairs(ListNode head) {
        ListNode dummy=new ListNode();
        dummy.next=head;
        ListNode pre=dummy;
        ListNode cur=head;
        
        while(cur!=null&&cur.next!=null){
            ListNode temp=cur.next;
            ListNode temp2=cur.next.next;
            pre.next=temp;
            temp.next=cur;
            cur.next=temp2;
            pre=cur;
            cur=temp2;
        }
        return dummy.next;
    }

28、随机链表的复制

public Node copyRandomList(Node head) {
        if(head==null){
            return null;
        }
        //创建一个哈希表,key是原节点,value是新节点
        Map<Node,Node> map=new HashMap<>();
        Node cur=head;
        //将原节点和新节点放入哈希表中
        while(cur!=null){
            Node newNode=new Node(cur.val);
            map.put(cur,newNode);
            cur=cur.next;
        }
        cur=head;
        //遍历原链表,设置新节点的next和random
        while(cur!=null){
            Node newNode=map.get(cur);
            if(cur.next!=null){
                newNode.next=map.get(cur.next);
            }
            if(cur.random!=null){
                newNode.random=map.get(cur.random);
            }
            cur=cur.next;
        }
        return map.get(head);
    }

29、排序链表

public ListNode sortList(ListNode head) {
        if(head==null || head.next==null){
            return head;
        }
        //找到分割点
        ListNode fast=head.next;
        ListNode slow=head;
        while(fast!=null && fast.next!=null){
            fast=fast.next.next;
            slow=slow.next;
        }
        ListNode cut=slow.next;
        slow.next=null;//断开链表 这步得加上 不然会栈溢出
        //递归
        ListNode left= sortList(head);
        ListNode right=sortList(cut);
        //合并
        return mergeTwoLists(left,right);
    }
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        ListNode head1=list1;
        ListNode head2=list2;
        ListNode newHead=new ListNode();
        ListNode result=newHead;
        while(head1!=null && head2!=null){
            if(head1.val<=head2.val){
                newHead.next=head1;
                head1=head1.next;
                newHead=newHead.next;
            }else{
                newHead.next=head2;
                head2=head2.next;
                newHead=newHead.next;
            }    
        }
        if(head1==null){
            newHead.next=head2;
        }else if(head2==null){
            newHead.next=head1;
        }
        return result.next;
    }

30、二叉树的中序排列

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res=new ArrayList<>();
        inorder(root,res);
        return res;
    }
    public void inorder (TreeNode root,List<Integer> res){
        if(root==null){
            return;
        }
        inorder(root.left,res);
        res.add(root.val);
        inorder(root.right,res);
    }
}

31、二叉树的最大深度

public int maxDepth(TreeNode root) {
        if(root==null){
            return 0;
        }
        int left=maxDepth(root.left);
        int right=maxDepth(root.right);
        return Math.max(left,right)+1;
    }

32、翻转二叉树

 public TreeNode invertTree(TreeNode root) {
//将以root为根节点的二叉树进行翻转 并且返回翻转之后的根节点
        if(root==null){
            return null;
        }
        TreeNode node1=invertTree(root.left);
        TreeNode node2=invertTree(root.right);
        root.left=node2;
        root.right=node1;
        return root;
    }

33、对称二叉树

    public boolean isSymmetric(TreeNode root) {
        if(root==null) return true;
        boolean flag=symmetric(root.left,root.right);
        return flag;     
    }
    public boolean symmetric(TreeNode root1,TreeNode root2) {
//判断root节点的左右子树是不是对称的 并且返回判断结果
        if(root1==null&&root2==null) return true;
        if(root1==null||root2==null) return false;     
        boolean flag1=symmetric(root1.left,root2.right);
        boolean flag2=symmetric(root1.right,root2.left);        
        return root1.val==root2.val&&flag1&&flag2;
    }

34、二叉树的直径

class Solution {
//每一条二叉树的「直径」长度,就是一个节点的左右子树的最大深度之和。
    int maxDiameter=0;
    public int diameterOfBinaryTree(TreeNode root) {
        maxDepth(root);
        return maxDiameter;
    }
    int maxDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        int leftMax = maxDepth(root.left);
        int rightMax = maxDepth(root.right);
        maxDiameter = Math.max(maxDiameter,leftMax + rightMax);
        return 1 + Math.max(leftMax, rightMax);
    }
}

35、二叉树的层序遍历

public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res=new ArrayList<List<Integer>>();
        if(root==null){ return res;}
        Queue<TreeNode> queue=new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()){
            int size=queue.size();
            List<Integer> list=new ArrayList<>();
            for(int i=0;i<size;i++){
                TreeNode node=queue.poll();
                list.add(node.val);
                if(node.left!=null){
                    queue.offer(node.left);
                }
                if(node.right!=null){
                    queue.offer(node.right);
                }
            }
            res.add(list);
        }
        return res;
    }

36、将有序数组转换为二叉搜索树

    public TreeNode sortedArrayToBST(int[] nums) {
        TreeNode root=traversal(nums,0,nums.length-1);
        return root;
    }
    public TreeNode traversal(int[] nums,int left,int right) {
//将数组从开始到结尾转换成二叉树 并且返回根节点
        if(left>right){
            return null;
        }
        int mid=(left+right)/2;
        TreeNode root=new TreeNode(nums[mid]);
        root.left=traversal( nums,left,mid-1);
        root.right=traversal(nums,mid+1,right);
        return root;
    }

37、验证二叉搜索树

    public boolean isValidBST(TreeNode node) {
        return isBst(node, Long.MIN_VALUE, Long.MAX_VALUE);
    }

    public boolean isBst(TreeNode node, long lower, long upper) {
//根节点是root的二叉树是不是搜索树
        if (node == null) {
            return true;
        }   
        if (node.val <= lower || node.val >= upper) {
            return false;
        }
        return isBst(node.left, lower, node.val) && isBst(node.right, node.val, upper);
}

38、二叉搜索树中第K小的元素

class Solution {
    public int kthSmallest(TreeNode root, int k) {
        return inorderTraversal(root).get(k-1);
    }
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res=new ArrayList<>();
        inorder(root,res);
        return res;
    }
    public void inorder (TreeNode root,List<Integer> res){
        if(root==null){
            return;
        }
        inorder(root.left,res);
        res.add(root.val);
        inorder(root.right,res);
    }
}

39、二叉树的右视图

public List<Integer> rightSideView(TreeNode root) {
        List<Integer> res=new ArrayList<Integer>();
        if(root==null){ return res;}
        Queue<TreeNode> queue=new LinkedList<>();
        queue.offer(root);
        while(!queue.isEmpty()){
            int size=queue.size();
            for(int i=0;i<size;i++){
                TreeNode node=queue.poll();
                if (i == size - 1) {
                res.add(node.val);
                }                
                if(node.left!=null){
                    queue.offer(node.left);
                }
                if(node.right!=null){
                    queue.offer(node.right);
                }
            }        
        }
        return res; 
    }

40、二叉树展开为链表

    public void flatten(TreeNode root) {
        if(root==null){
            return;
        }
        flatten(root.left);
        flatten(root.right);
        TreeNode left=root.left;
        TreeNode right=root.right;
        //将左子树作为右子树
        root.left=null;
        root.right=left;
        //将原先的右子树接到当前右子树的末端
        TreeNode p=root;
        while(p.right!=null){
            p=p.right;
        }
        p.right=right;
    }

41、从前序与中序遍历序列构造二叉树

    public TreeNode buildTree(int[] preorder, int[] inorder) {
        return build(preorder,0,preorder.length-1,inorder,0,inorder.length-1);
    }
    public TreeNode build(int[] preorder,int prestart,int preend,int[]inorder,int instart,int inend){
        //build函数是找到以前序中序排列的根节点
        if(prestart>preend) return null;
        int rootval=preorder[prestart];
        TreeNode root=new TreeNode(rootval);
        int index=0;
        for(int i=instart;i<=inend;i++){
            if(inorder[i]==rootval){
                index=i;
                break;
            }
        }
        int leftsize=index-instart;
        root.left=build(preorder,prestart+1,prestart+leftsize,inorder,instart,index-1);
        root.right=build(preorder,prestart+leftsize+1,preend,inorder,index+1,inend);
        return root;
    }

42、路径总和

    public int pathSum(TreeNode root, int targetSum) {
        if(root==null) return 0;
        int num=rootSum(root,targetSum);
        num+=pathSum(root.left,targetSum);
        num+=pathSum(root.right,targetSum);
        return num;
    }
    public int rootSum(TreeNode root,long targetSum){
        int num=0;
        if(root==null){return 0;}
        long val=root.val;
        if(val==targetSum) num++;
        num+=rootSum(root.left,targetSum-val);
        num+=rootSum(root.right,targetSum-val);
        return num;
    }

43、二叉树的最近公共祖先


   public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root==null||root==p||root==q){return root;}
        TreeNode left=lowestCommonAncestor(root.left,p,q);
        TreeNode right=lowestCommonAncestor(root.right,p,q);
        if(left==null) return right;
        if(right==null) return left;
        return root;
    }
    

44、有效的括号

public boolean isValid(String s) {
        Stack<Character> stack=new Stack();
        HashMap<Character,Character> map=new HashMap<>();
        map.put('(',')');
        map.put('{','}');
        map.put('[',']');
        map.put('?','?');
        stack.push('?');
        for(int i=0;i<s.length();i++){
            char c=s.charAt(i);
            if(map.containsKey(c)){
//注意是containsKey
                stack.push(c);
            }else if(map.get(stack.pop())!=c){ 
//调用了stack.pop()元素就已经弹出了
                return false;
            }
        }
        return stack.size()==1;
    }

45、字符串解码

public String decodeString(String s) {
        Stack<Integer> stackMulti=new Stack();
        Stack<String> stackRes=new Stack();//存放中间结果的
        StringBuilder sb=new StringBuilder();
        int multi=0;
        for(int i=0;i<s.length();i++){
            char c=s.charAt(i);
            if(c>='0'&&c<='9'){
                multi=multi*10+Integer.parseInt(c+"");                
            }else if(c=='['){
                stackMulti.push(multi);//为括号内字符解码做乘积的准备
                stackRes.push(sb.toString());//把之前的结果进行存放
                multi=0;
                sb=new StringBuilder();//存放括号内的字符
            }else if(c==']'){
                StringBuilder temp=new StringBuilder();
                int curMulti=stackMulti.pop();
                for(int j=0;j<curMulti;j++){
                    temp.append(sb);
                }
                sb=new StringBuilder(stackRes.pop()+temp);
            }else{
                sb.append(c);
            }
        }
        return sb.toString();
    }

46、每日温度

public int[] dailyTemperatures(int[] temperatures) {
        int[] res=new int[temperatures.length];
        Stack<Integer> stack=new Stack();        
        for(int i=0;i<temperatures.length;i++){
            int c=temperatures[i];
            while(!stack.isEmpty()&&temperatures[stack.peek()]<c){
                int j=stack.pop();
                res[j]=i-j;
            }
            stack.push(i);
        }
        return res;
    }

47、数组中的第K个最大元素

    public int findKthLargest(int[] nums, int k) {
       PriorityQueue<Integer> queue=new PriorityQueue();
       for(int num:nums){
        queue.offer(num);
        if(queue.size()>k){
            queue.poll();
        }
       }
       return queue.peek();
    }

48、前K个高频元素

    public int[] topKFrequent(int[] nums, int k) {
        HashMap<Integer,Integer> map=new HashMap<>();
        for(int num:nums){
            map.put(num,map.getOrDefault(num,0)+1);
        }
        PriorityQueue<Integer> queue=new PriorityQueue<>(
            (Integer a,Integer b)->map.get(a)-map.get(b));
//按照map的值即出现的次数构造的小顶堆
        for(Integer key:map.keySet()){
            queue.offer(key);
            if(queue.size()>k){
                queue.poll();
            }
        }
        int [] res=new int[k];
        for(int i=0;i<k;i++){
            res[i]=queue.peek();
            queue.poll();
        }
        return res;
    }

动态规划

49、爬楼梯

    public int climbStairs(int n) {
        int[] dp = new int[n + 1];
        dp[0] = 1;
        dp[1] = 1;
        for (int i = 2; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }

50、杨辉三角

    public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> res=new ArrayList<>();
        for(int i=0;i<numRows;i++){
            List<Integer> row=new ArrayList<>();
            for(int j=0;j<=i;j++){
                if(j==0||j==i){
                    row.add(1);
                }else{
                    row.add(res.get(i-1).get(j-1)+res.get(i-1).get(j));
                }
            }
        res.add(row);        
        }
        return res;
    }//没懂的弄个双重循环

51、打家劫舍

    public int rob(int[] nums) {
        int [] dp=new int[nums.length+1];
        dp[0]=0;
        dp[1]=nums[0];
        for(int i=2;i<dp.length;i++ ){
            dp[i]=Math.max(dp[i-1],dp[i-2]+nums[i-1]);
        }
        return dp[nums.length];
    }

52、完全平方数

    public int numSquares(int n) {
        int [] dp=new int[n+1];
        Arrays.fill(dp,n);
        dp[0]=0;
        dp[1]=1;
        for(int i=2;i<n+1;i++){
            for(int j=1;j * j <= i; j++){
                dp[i]=Math.min(dp[i-j*j]+1,dp[i]);
            }    
        }
        return dp[n];
    }

53、零钱兑换

    public int coinChange(int[] coins, int amount) {
        int[] dp=new int[amount+1];
        Arrays.fill(dp,amount+1);//这里为什么填充的是amount+1呢
        dp[0]=0;
        for(int i=1;i<dp.length;i++){
            for(int j=0;j<coins.length;j++){
                if(i-coins[j]<0){
                    continue;
                }else{
                    dp[i]=Math.min(dp[i-coins[j]]+1,dp[i]);
                }    
            }
        } 
        return dp[amount]>amount?-1:dp[amount];
    }

54、单词拆分

    public boolean wordBreak(String s, List<String> wordDict) {
        boolean [] dp=new boolean[s.length()+1];
        dp[0]=true;
        Set<String> set=new HashSet<>();
        for(int i=0;i<wordDict.size();i++){
            set.add(wordDict.get(i));
        }
        for(int i=1;i<s.length()+1;i++){
            for(int j=0;j<i;j++){
                if(dp[j]&&set.contains(s.substring(j,i))){
                    dp[i]=true;
                    break;
                }
            }
        }
        return dp[s.length()];  
    }

55、最长递增子序列

    public int lengthOfLIS(int[] nums) {
        if (nums.length == 0) {
            return 0;
        }
        int[] dp = new int[nums.length];
        dp[0] = 1;
        int maxans = 1;
        for (int i = 1; i < nums.length; i++) {
            dp[i] = 1;
            for (int j = 0; j < i; j++) {
                if (nums[i] > nums[j]) {
                    dp[i] = Math.max(dp[i], dp[j] + 1);
                }
            }
            maxans = Math.max(maxans, dp[i]);
        }
        return maxans;
//最大值不一定是出现在最后的
    }

56、乘积最大子数组

    public int maxProduct(int[] nums) {
        int max=Integer.MIN_VALUE;
        int imax=1;
        int imin=1;
        for(int i=0;i<nums.length;i++){
            if(nums[i]<0){
                int temp=imax;
                imax=imin;
                imin=temp;
            }
            imax=Math.max(imax*nums[i],nums[i]);
            imin=Math.min(imin*nums[i],nums[i]);
            max=Math.max(max,imax);
        }
        return max;   
    }

57、分割等和子集

    public boolean canPartition(int[] nums) {
        int sum=0;
        for(int i:nums){
            sum+=i;
        }
        int target=sum/2;
        if(sum%2!=0){
            return false;
        }
        int []dp=new int[target+1];
       
        for(int i=0;i<nums.length;i++){
            for(int j=target;j>=nums[i];j--){  
    //背包容量是target,放入的不能比容量大;并且每个元素不能重复放入,所以要从大到小遍历              
                dp[j] = Math.max(dp[j], dp[j - nums[i]] + nums[i]);
            }
                if(dp[target]==target){
                   return true;
                }
        }
        return dp[target]==target;        
    }

58、不同路径

    public int uniquePaths(int m, int n) {
        int [][] dp=new int[m][n];
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(i==0||j==0){
                    dp[i][j]=1;
                }else{
                    dp[i][j]=dp[i-1][j]+dp[i][j-1];
                }
            }
        }
        return dp[m-1][n-1];
    }

59、最小路径和

    public int minPathSum(int[][] grid) {
        int m=grid.length;
        int n=grid[0].length;
        int [][] dp=new int [m][n];
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(i==0&&j==0){
                    dp[i][j]=grid[i][j];
                }else if(i==0){
                    dp[i][j]=dp[i][j-1]+grid[i][j];
                }else if(j==0){
                    dp[i][j]=dp[i-1][j]+grid[i][j];
                }else{
                    dp[i][j]=Math.min(dp[i-1][j],dp[i][j-1])+grid[i][j];
                }
            }
        }
        return dp[m-1][n-1];
    }

60、最长回文子串

    public String longestPalindrome(String s) {
        if(s==null||s.length()<2){
            return s;
        }
        int len=s.length();
        int maxStart=0;
        int maxEnd=0;
        int maxLen=1;
        boolean[][]dp=new boolean[len][len];
        for(int i=1;i<len;i++){
            for(int j=0;j<i;j++){
                if(s.charAt(j)==s.charAt(i)&&(i-j<=2||dp[j+1][i-1])){
                //重点是转移方程
                    dp[j][i]=true;
                    if(i-j+1>maxLen){
                        maxLen=i-j+1;
                        maxStart=j;
                        maxEnd=i;
                    }
                }
            }
        }
        return s.substring(maxStart,maxEnd+1);
    }

61、最长公共子序列

    public int longestCommonSubsequence(String text1, String text2) {
        int m=text1.length();
        int n=text2.length();
        int [][] dp=new int[m+1][n+1];
        //dp[i][j] 表示 text1[0:i-1] 和 text2[0:j-1] 的最长公共子序列的长度
        //text1[0:i-1] 表示的是 text1 的 第 0 个元素到第 i - 1 个元素,两端都包含
        for(int i=1;i<m+1;i++){
            for(int j=1;j<n+1;j++){
                if(text1.charAt(i-1)==text2.charAt(j-1)){
                    dp[i][j]=dp[i-1][j-1]+1;
                }else{
                    dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1]);
                }
            }
        }
        return dp[m][n];
    }

二分查找

62、搜索插入位置

    public int searchInsert(int[] nums, int target) {
        int left=0;
        int right=nums.length-1;
        //注意是<=
        while(left<=right){
            int middle=(left+right)/2;
            if(nums[middle]<target){
                left=middle+1;
            }else if(nums[middle]>target){
                right=middle-1;
            }else{
                return middle;
            }
        }
        return left;

    }

63、搜索二维矩阵

    public boolean searchMatrix(int[][] matrix, int target) {
        int m=matrix.length;
        int n=matrix[0].length;
        int left=0;
        int right=m*n-1;
        while(left<=right){
            int mid=(left+right)/2;
            if(matrix[mid/n][mid%n]<target){
                //坐标做一个映射就可以了
                left=mid+1;
            }else if(matrix[mid/n][mid%n]>target){
                right=mid-1;
            }else{
                return true;
            }
        }
        return false;
    }

64、 在排序数组中查找元素的第一个和最后一个位置

    public int[] searchRange(int[] nums, int target) {
        int left=0;
        int right=nums.length-1;
        while(left<=right){
            int mid=(left+right)/2;
            if(target==nums[mid]){
                while(target!=nums[left])  left++;//继续循环找就好
                while(target!=nums[right]) right--;
                return new int[]{left,right};
            }else if(target>nums[mid]){
                left=mid+1;
            }else {
                right=mid-1;
            }
        }
        return new int[]{-1,-1};
    }

65、搜索旋转排序数组

66、寻找旋转排序数组中的最小值

贪心算法

67、买卖股票的最佳时机

public int maxProfit(int[] prices) {
        int min=Integer.MAX_VALUE;
        int max=0;
        for(int i=0;i<prices.length;i++){
            if(prices[i]<min){
                min=prices[i];
            }else if(prices[i]-min>max){
                max=prices[i]-min;
            }//中心思想就是在这一天要么买入要么卖出
        }
        return max;
    }

68、跳跃格子

    public boolean canJump(int[] nums) {
        int n=nums.length;
        int maxReach=0;
        for(int i=0;i<n;i++){
            if(i<=maxReach){//这个点是在最大可达范围之内的话,才会去更新
                maxReach=Math.max(maxReach,i+nums[i]);
                if(maxReach>=n-1){
                    return true;
                }
            }
        }
        return false;
    }

69、跳跃格子2

    public int jump(int[] nums) {
        int pos=nums.length-1;
        int step=0;
        while(pos>0){
            for(int i=0;i<pos;i++){
                if(i+nums[i]>=pos){
                    pos=i;
                    step++;
                    break;
                }
            }
        }
        return step;
    }

70、划分字母区间

    public List<Integer> partitionLabels(String s) {
        int [] last=new int[26];
        int length=s.length();
        for(int i=0;i<length;i++){
            last[s.charAt(i)-'a']=i;
        }//把26个字母中对应字符串中的最远位置记录下来
        List<Integer> res=new ArrayList<>();
        int start=0;
        int end=0;
        for(int i=0;i<length;i++){
            end=Math.max(end,last[s.charAt(i)-'a']);
            if(i==end){//在这之前出现过的,仍然没有更大的end,
            //此时就说明到达了终点
                res.add(end-start+1);
                start=end+1;
            }
        }
        return res;
    }

回溯

71、子集

class Solution {
    List<List<Integer>> res=new ArrayList<>();
    LinkedList<Integer> path=new LinkedList<>();
    public List<List<Integer>> subsets(int[] nums) {
        back(nums,0);
        return res;
    }
    public void back(int[] nums,int start){
        res.add(new ArrayList<>(path));
        for(int i=start;i<nums.length;i++){
            //元素是无序的,取过的元素不会重复取,for从start开始
            path.add(nums[i]);
            back(nums,i+1);//元素不重复取
            path.removeLast();
        }
    }
}

72、分割回文串

class Solution {
    List<List<String>> res=new ArrayList<>();
    List<String> cur=new ArrayList<>();
    public List<List<String>> partition(String s) {
        back(s,0,new StringBuilder());
        return res;
    }
    public void back(String s,int start,StringBuilder sb){
        if(start==s.length()){
            res.add(new ArrayList<>(cur));
            return ;
        }
        for(int i=start;i<s.length();i++){
            sb.append(s.charAt(i));
            if(check(sb)){
                cur.add(sb.toString());
                back(s,i+1,new StringBuilder());
                cur.remove(cur.size()-1);
            }
        }
    }
    public boolean check(StringBuilder sb){
        for(int i=0;i<sb.length()/2;i++){
            if(sb.charAt(i)!=sb.charAt(sb.length()-1-i)){
                return false;
            }
        }
        return true;
    }
}

73、电话号码的字母组合

class Solution {
    List<String> res=new ArrayList<>();
    public List<String> letterCombinations(String digits) {
       if(digits==null||digits.length()==0){
        return res;
    
       }
       String[] arr={"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
       back(digits,arr,0);
       return res;
        
    }
    StringBuilder temp=new StringBuilder();
    public void back(String digits,String[] arr,int index){
        if(index==digits.length()){
            res.add(temp.toString());
            return;
        }
        String str=arr[digits.charAt(index)-'0'];
        for(int i=0;i<str.length();i++){
            temp.append(str.charAt(i));
            back(digits,arr,index+1);
            temp.deleteCharAt(temp.length()-1);
        }
    }
}

74、组合总和

class Solution {
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        List<List<Integer>> res=new ArrayList<>();
        Arrays.sort(candidates);
        back(res,new ArrayList<>(),candidates,target,0,0);
        return res;
    }
    public void back(List<List<Integer>> res,List<Integer> path,int[] candidates,int target,int sum,int index){
//一个集合求组合,需要index
        if(sum==target){
            res.add(new ArrayList<>(path));
            return;
        }
        for(int i=index;i<candidates.length;i++){
            if(sum+candidates[i]>target) break;
            path.add(candidates[i]);
            back(res,path,candidates,target,sum+candidates[i],i);
//元素可以重复选取,所以是i
            path.remove(path.size()-1);
        }
        
    }
}

75、括号生成

class Solution {
    StringBuilder track=new StringBuilder();
    List<String> res=new ArrayList<>();
    public List<String> generateParenthesis(int n) {
        if(n==0){
            return res;
        }
        back(n,n);
        return res;
    }
    public void back(int left,int right){//左右括号剩余的数量
        if(right<left) return;
        if(left<0||right<0) return;
        if(left==0&&right==0){
            res.add(track.toString());
            return;
        }
        track.append('(');
        back(left-1,right);
        track.deleteCharAt(track.length()-1);
        track.append(')');
        back(left,right-1);
        track.deleteCharAt(track.length()-1);
    }
}

76、单词搜索

class Solution {
    public boolean exist(char[][] board, String word) {
        char[] words=word.toCharArray();
        for(int i=0;i<board.length;i++){
            for(int j=0;j<board[0].length;j++){
                if(dfs(board,words,i,j,0)) return true;
            }
        }
        return false;
    }
    public boolean dfs(char[][]board,char[] word,int i,int j,int k){
        if(i>=board.length||i<0||j>=board[0].length||j<0||board[i][j]!=word[k]) 
        return false;
        if(k==word.length-1) return true;
        board[i][j]=' ';//
        boolean res=dfs(board,word,i+1,j,k+1)||
                    dfs(board,word,i-1,j,k+1)||
                    dfs(board,word,i,j+1,k+1)||
                    dfs(board,word,i,j-1,k+1);
        board[i][j]=word[k];//还原至当前初始值
        return res;
    }
}

77、全排列

class Solution {
    List<List<Integer>> res=new ArrayList<>();
    LinkedList<Integer> path=new LinkedList<>();
    public List<List<Integer>> permute(int[] nums) {
        int n=nums.length;
        if(n==0) return res;
        back(nums,path);
        return res; 
    }
    public void back(int [] nums,LinkedList<Integer> path){
        //排列是有序的,处理排列就不用start了
        if(path.size()==nums.length){
            res.add(new ArrayList<>(path));
        }
        for(int i=0;i<nums.length;i++){
            if(path.contains(nums[i])) continue;
            path.add(nums[i]);
            back(nums,path);
            path.removeLast();
        }
    }
}

技巧

78、只出现一次的数字

79、多数元素

80、颜色分类

81、下一个排列

class Solution {
    public void nextPermutation(int[] nums) {
        int i=nums.length-2;
        while(i>=0&&nums[i]>=nums[i+1]){
            i--;
        }
        if(i>=0){
            int j=nums.length-1;
            while(j>=0&&nums[i]>=nums[j]){
                j--;
            }
            swap(nums,i,j);
        }
        reverse(nums,i+1);
        
    }
    public void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
    public void reverse(int[] nums, int start) {
        int left = start, right = nums.length - 1;
        while (left < right) {
            swap(nums, left, right);
            left++;
            right--;
        }
    }
}

82、寻找重复数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值