LeectCode常考算法(Java實現)

數組

1 數組中重複的數字

在這裏插入圖片描述
主要思想是讓每個數字回到自己對應的索引位置,如果已經存在就代表重複了。

	public int findRepeatNumber(int[] nums) {
        for(int i=0;i<nums.length;i++){
            //獲取當前位置的數字
            int nowNumber=nums[i];
            //如果當前數字和目前索引不等
            if(nowNumber!=i){
                //如果當前數字對應位置已經存放了當前數字,代表重複
                if(nowNumber==nums[nowNumber])
                    return nowNumber;
                else{
                    //置換
                    nums[i]=nums[nowNumber];
                    nums[nowNumber]=nowNumber;
                }
            }
        }
        return 0;
    }

2 二維數組中的查找

在這裏插入圖片描述
從二維數組的右上角開始查找,比目標值小就下移,大就左移。

public boolean findNumberIn2DArray(int[][] matrix, int target) {
        if(matrix.length==0||matrix[0].length==0)
            return false;
        //行條件
        int Row=matrix.length;
        //初始行和列
        int row=0;
        int col=matrix[0].length-1;
        int nowNumber=matrix[row][col];
        while(row<Row&&col>=0){
            if(matrix[row][col]==target)
                return true;
            else if(matrix[row][col]<target)
                row++;
            else
                col--;
        }
        return false;
    }

3 和爲s的兩個數字

在這裏插入圖片描述
雙指針

	public int[] twoSum(int[] nums, int target) {
        int i=0;
        int j=nums.length-1;
        int sum=0;
        while(i<j){
            sum=nums[i]+nums[j];
            if(sum>target)
                j--;
            else if(sum<target)
                i++;
            else
                return new int[]{nums[i],nums[j]};
        }
        return new int[2];
    }

4 旋轉數組的最小數字

在這裏插入圖片描述
找到第一個比前一個元素小的數字,沒找到就返回第一個

	public int minArray(int[] numbers) {
        for(int i=1;i<numbers.length;i++){
            if(numbers[i]<numbers[i-1])
                return numbers[i];
        }
        return numbers[0];
    }

5 打印從1到最大的n位數

在這裏插入圖片描述

public int[] printNumbers(int n) {
        int number=0;
        while(n!=0){
            number=number*10+9;
            n--;
        }
        int[] arr=new int[number];
        for(int i=0;i<number;i++)
            arr[i]=i+1;
        return arr;
    }

6 調整數組順序

在這裏插入圖片描述

	public int[] exchange(int[] nums) {
        int l=0;
        int r=nums.length-1;
        while(l<r){
            while(l<=r&&nums[l]%2!=0)
                l++;
            while(l<=r&&nums[r]%2==0)
                r--;
            if(l<r){
                int temp=nums[l];
                nums[l]=nums[r];
                nums[r]=temp;
            }
        }
        return nums;
    }

7 順時針打印矩陣

在這裏插入圖片描述

	public int[] spiralOrder(int[][] matrix) {
        if(matrix.length==0||matrix[0].length==0)
            return new int[0];
        int m=matrix.length;
        int n=matrix[0].length;
        int[] arr=new int[m*n];
        int index=0;
        int top=0,bottom=m-1;
        int left=0,right=n-1;
        while(true){
            //左向右
            for(int i=left;i<=right;i++)
                arr[index++]=matrix[top][i];
            if(++top>bottom) break;
            //上向下
            for(int i=top;i<=bottom;i++)
                arr[index++]=matrix[i][right];
            if(--right<left) break;
            //右向左
            for(int i=right;i>=left;i--)
                arr[index++]=matrix[bottom][i];
            if(--bottom<top) break;
            //下向上
            for(int i=bottom;i>=top;i--)
                arr[index++]=matrix[i][left];
            if(++left>right) break;
        }
        return arr;
    }

8 數組中超過一次的數字

在這裏插入圖片描述

public int majorityElement(int[] nums) {
        Arrays.sort(nums);
        return nums[nums.length/2];
    }

9 最小的k個數

在這裏插入圖片描述

	public int[] getLeastNumbers(int[] arr, int k) {
        Arrays.sort(arr);
        return Arrays.copyOf(arr,k);
    }

10 連續子數組最大和

在這裏插入圖片描述

	public int maxSubArray(int[] nums) {
        if(nums.length==0)
            return 0;
        int maxSum=nums[0];
        int tempSum=nums[0];
        for(int i=1;i<nums.length;i++){
            if(tempSum<0)
                tempSum=nums[i];
            else
                tempSum+=nums[i];
            maxSum=Math.max(maxSum,tempSum);
        }
        return maxSum;
    }

11 禮物的最大價值

在這裏插入圖片描述

	public int maxValue(int[][] grid) {
        int row=grid.length;
        int col=grid[0].length;
        //第一列
        for(int i=1;i<row;i++){
            grid[i][0]+=grid[i-1][0];
        }
        //第一行
        for(int i=1;i<col;i++){
            grid[0][i]+=grid[0][i-1];
        }
        //動態規劃
        for(int i=1;i<row;i++){
            for(int j=1;j<col;j++){
                grid[i][j]+=Math.max(grid[i-1][j],grid[i][j-1]);
            }
        }
        return grid[row-1][col-1];
    }

12 把數組排成最小的數

在這裏插入圖片描述

	public String minNumber(int[] nums) {
        String[] strs=new String[nums.length];
        for(int i=0;i<nums.length;i++)
            strs[i]= String.valueOf(nums[i]);
        Arrays.sort(strs,(x,y)->(x+y).compareTo(y+x));
        StringBuilder sb = new StringBuilder();
        for(String str:strs)
            sb.append(str);
        return sb.toString();
    }

13 在排序數組查找數字

在這裏插入圖片描述

	public int search(int[] nums, int target) {
        int left=0;
        int right=nums.length-1;
        while(left<=right){
            int mid=left+((right-left)>>1);
            if(nums[mid]<target)
                left=mid+1;
            else if(nums[mid]>target)
                right=mid-1;
            else{
                int cnt=1;
                int index=mid-1;
                while(index>=0&&nums[index]==target){
                    cnt++;
                    index--;
                }
                index=mid+1;
                while(index<nums.length&&nums[index]==target){
                    cnt++;
                    index++;
                }
                return cnt;
            }
        }
        return 0;
    }

14 0~n-1缺失的數字

在這裏插入圖片描述

	public int missingNumber(int[] nums) {
        for(int i=0;i<nums.length;i++){
            if(i!=nums[i])
                return i;
        }
        return nums.length;
    }

15 和爲s的連續正數序列

在這裏插入圖片描述

public int[][] findContinuousSequence(int target) {
        List<int[]> res=new ArrayList<>();
        int left=1;
        int right=2;
        int sum=0;
        while(left<right){
            sum=(left+right)*(right-left+1)/2;
            if(sum>target)
                left++;
            else if(sum<target)
                right++;
            else{
                int[] arr=new int[right-left+1];
                int index=0;
                for(int i=left;i<=right;i++){
                    arr[index++]=i;
                }
                res.add(arr);
                left++;
            }
        }
        return res.toArray(new int[0][]);
    }

16 買賣股票

在這裏插入圖片描述
動態規劃

public int maxProfit(int[] prices) {
        if(prices.length==0)
            return 0;
        int maxProfit=0;
        int minBuy=prices[0];
        for(int i=1;i<prices.length;i++){
            int profit=prices[i]-minBuy;
            maxProfit=Math.max(maxProfit,profit);
            minBuy=Math.min(minBuy,prices[i]);
        }
        return maxProfit;
    }

17 構建乘積數組

在這裏插入圖片描述

public int[] constructArr(int[] a) {
        int[] b=new int[a.length];
        for(int i=0,n=1;i<a.length;i++){
            b[i]=n;
            n*=a[i];
        }
        for(int i=a.length-1,n=1;i>=0;i--){
            b[i]*=n;
            n*=a[i];
        }
        return b;
    }

18 撲克牌中的順子

在這裏插入圖片描述

public boolean isStraight(int[] nums) {
        int joker=0;
        Arrays.sort(nums);
        for(int i=0;i<4;i++){
            if(nums[i]==0)
                joker++;
            else if(nums[i]==nums[i+1])
                return false;
        }
        return nums[4]-nums[joker]<5;
    }


二叉樹

1 樹的子結構

在這裏插入圖片描述

	public boolean isSubStructure(TreeNode A, TreeNode B) {
        if(A==null||B==null)
            return false;
        return isSub(A,B)||isSubStructure(A.left,B)||isSubStructure(A.right,B);
    }

    public boolean isSub(TreeNode A,TreeNode B){
        if(B==null)
            return true;
        if(A==null||A.val!=B.val)
            return false;
        return isSub(A.left,B.left)&&isSub(A.right,B.right);
    }

2 二叉樹的鏡像

在這裏插入圖片描述

	public TreeNode mirrorTree(TreeNode root) {
        if(root!=null){
            TreeNode left=mirrorTree(root.left);
            TreeNode right=mirrorTree(root.right);
            root.left=right;
            root.right=left;
        }
        return root;
    }

3 判斷對稱二叉樹

在這裏插入圖片描述

	public boolean isSymmetric(TreeNode root) {
        if(root==null)
            return true;
        return isSymmetric(root.left,root.right);
    }

    public boolean isSymmetric(TreeNode n1,TreeNode n2){
        if((n1!=null&&n2==null)||(n1==null&&n2!=null))
            return false;
        if(n1==null&&n2==null)
            return true;
        if(n1.val!=n2.val)
            return false;
        else{
            return isSymmetric(n1.left,n2.right)&&isSymmetric(n1.right,n2.left);
        }
    }

4 從上到下打印二叉樹

在這裏插入圖片描述

	public int[] levelOrder(TreeNode root) {
        List<TreeNode> treeList=new ArrayList<>();
        List<Integer> list=new ArrayList<>();
        if(root==null)
            return new int[0];
        treeList.add(root);
        while(treeList.size()!=0){
            TreeNode temp=treeList.get(0);
            list.add(temp.val);
            treeList.remove(0);
            if(temp.left!=null){
                treeList.add(temp.left);
            }
            if(temp.right!=null){
                treeList.add(temp.right);
            }
        }

        //返回結果
        int[] res=new int[list.size()];
        for(int i=0;i<res.length;i++)
            res[i]=list.get(i);
        return res;
    }

5 從上到下打印二叉樹2

在這裏插入圖片描述

	public List<List<Integer>> levelOrder(TreeNode root) {
        List<TreeNode> treeList=new ArrayList<>();
        List<Integer> temp;
        List<List<Integer>> resultList=new ArrayList<>();
        if(root!=null){
            treeList.add(root);
            while(treeList.size()!=0){
                int n=treeList.size();
                temp=new ArrayList<>();
                for(int i=0;i<n;i++){
                    TreeNode node=treeList.remove(0);
                    temp.add(node.val);
                    if(node.left!=null)
                        treeList.add(node.left);
                    if(node.right!=null)
                        treeList.add(node.right);
                }
                resultList.add(temp);
            }
        }
        return resultList;
    }

6 二叉搜索樹第k大結點

在這裏插入圖片描述
中序遍歷

public int kthLargest(TreeNode root, int k) {
        List<Integer> list=new ArrayList<>();
        inOrder(root,list);
        return list.get(list.size()-k);
    }

    public void inOrder(TreeNode root,List<Integer> list){
        if(root!=null){
            inOrder(root.left,list);
            list.add(root.val);
            inOrder(root.right,list);
        }
    }

7 二叉樹的深度

在這裏插入圖片描述

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

8 判斷平衡二叉樹

	public boolean isBalanced(TreeNode root) {
        if(root==null)
            return true;
        int hL=maxDepth(root.left);
        int hR=maxDepth(root.right);
        return !(Math.abs(hL-hR)>1)&&isBalanced(root.left)&&isBalanced(root.right);
    }

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

9 二叉搜索樹的最近公共祖先

在這裏插入圖片描述

	public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
        if(root!=null){
            if(p.val<root.val&&q.val<root.val)
                return lowestCommonAncestor(root.left,p,q);
            else if(p.val>root.val&&q.val>root.val)
                return lowestCommonAncestor(root.right,p,q);
            else
                return root;
        }
        return root;
    }

10 二叉樹的最近公共祖先

在這裏插入圖片描述

	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;
    }

字符串

1 替換空格

在這裏插入圖片描述
利用StringBuilder

public String replaceSpace(String s) {
        StringBuilder sb=new StringBuilder();
        for(int i=0;i<s.length();i++){
            if(s.charAt(i)==' ')
                sb.append("%20");
            else
                sb.append(s.charAt(i));
        }
        return sb.toString();
    }

2 第一個只出現一次的字符

在這裏插入圖片描述

public char firstUniqChar(String s) {
        int[] words=new int[128];
        for (int i = 0; i <s.length() ; i++) {
            words[s.charAt(i)]++;
        }
        for (int i = 0; i <s.length() ; i++) {
            if(words[s.charAt(i)]==1)
                return s.charAt(i);
        }
        return ' ';
    }

3 數字翻譯字符串

在這裏插入圖片描述
動態規劃

	public int translateNum(int num) {
        String number = String.valueOf(num);
        int[] dp=new int[number.length()+1];
        dp[0]=1;
        dp[1]=1;
        for(int i=2;i<dp.length;i++){
            String s = number.substring(i - 2, i);
            if(s.compareTo("10")>=0&&s.compareTo("25")<=0)
                dp[i]=dp[i-1]+dp[i-2];
            else 
                dp[i]=dp[i-1];
        }
        return dp[dp.length-1];
    }

4 左旋字符串

在這裏插入圖片描述

	public String reverseLeftWords(String s, int n) {
        return s.substring(n)+s.substring(0,n);
    }

5 翻轉單詞字符串

在這裏插入圖片描述

	public String reverseWords(String s) {
        s=s.trim();
        int j=s.length()-1;
        int i=j;
        StringBuilder sb=new StringBuilder();
        while(i>=0){
            while(i>=0&&s.charAt(i)!=' ')
                i--;
            sb.append(s.substring(i+1,j+1)+" ");
            while(i>=0&&s.charAt(i)==' ')
                i--;
            j=i;
        }
        return sb.toString().trim();
    }


鏈表

1 從尾到頭打印鏈表

在這裏插入圖片描述
利用棧的LIFO

public int[] reversePrint(ListNode head) {
        Stack<Integer> stack=new Stack<>();
        while(head!=null){
            stack.push(head.val);
            head=head.next;
        }
        int[] res=new int[stack.size()];
        for(int i=0;i<res.length;i++){
            res[i]=stack.pop();
        }
        return res;
    }

2 刪除鏈表的結點

在這裏插入圖片描述

	public ListNode deleteNode(ListNode head, int val) {
        ListNode pre=new ListNode(-1);
        ListNode res=pre;
        pre.next=head;
        while(head!=null){
            if(head.val==val){
                pre.next=head.next;
                break;
            }
            pre=pre.next;
            head=head.next;
        }
        return res.next;
    }

3 鏈表中倒數第k個結點

在這裏插入圖片描述

public ListNode getKthFromEnd(ListNode head, int k) {
        ListNode pre=new ListNode(-1);
        pre.next=head;
        ListNode p=pre;
        ListNode q=pre;
        for(int i=0;i<k;i++){
            q=q.next;
        }
        while(q!=null){
            p=p.next;
            q=q.next;
        }
        return p;
    }

4 反轉鏈表

在這裏插入圖片描述

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

5 合併鏈表

在這裏插入圖片描述

public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        ListNode pre=new ListNode(-1);
        ListNode res=pre;
        while(l1!=null&&l2!=null){
            if(l1.val<=l2.val){
                pre.next=new ListNode(l1.val);
                l1=l1.next;
            }else{
                pre.next=new ListNode(l2.val);
                l2=l2.next;
            }
            pre=pre.next;
        }
        while(l1!=null){
            pre.next=new ListNode(l1.val);
            pre=pre.next;
            l1=l1.next;
        } 
        while(l2!=null){
            pre.next=new ListNode(l2.val);
            pre=pre.next;
            l2=l2.next;
        }
        return res.next;
    }

6 兩個鏈表的第一個公共結點

在這裏插入圖片描述

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if(headA==null&&headB==null)
            return null;
        ListNode p=headA;
        ListNode q=headB;
        while(p!=q){
            p=p==null?headB:p.next;
            q=q==null?headA:q.next;
        }
        return p;
    }

數學

1 整數翻轉

在這裏插入圖片描述

	public int reverse(int x) {
        int res=0;
        while (x!=0){
            int pop=x%10;
            x/=10;
            if(res>Integer.MAX_VALUE/10||(res==Integer.MAX_VALUE/10&&pop>7))
                return 0;
            if(res<Integer.MIN_VALUE/10||(res==Integer.MIN_VALUE/10&&pop<-8))
                return 0;
            res=res*10+pop;
        }
        return res;
    }

2 迴文數

在這裏插入圖片描述

	public boolean isPalindrome(int x) {
        if(x<0||(x%10==0&&x!=0))
            return false;
        int rev=0;
        while (x>rev){
            rev=rev*10+x%10;
            x/=10;
        }
        return rev==x||rev/10==x;
    }

3 剪繩子

在這裏插入圖片描述

	public int cuttingRope(int n) {
        if(n<=3)
            return n-1;
        int a=n/3;
        int b=n%3;
        if(b==0)
            return (int)Math.pow(3,a);
        if(b==1)
            return (int)Math.pow(3,a-1)*4;
        return (int)Math.pow(3,a)*2;        
    }

4 醜數

在這裏插入圖片描述

public int nthUglyNumber(int n) {
        int[] dp=new int[n];
        dp[0]=1;
        int a=0,b=0,c=0;
        for(int i=1;i<n;i++){
            int num1=dp[a]*2;
            int num2=dp[b]*3;
            int num3=dp[c]*5;
            int minNum=Math.min(Math.min(num1,num2),num3);
            dp[i]=minNum;
            if(num1==minNum)
                a++;
            if(num2==minNum)
                b++;
            if(num3==minNum)
                c++;
        }
        return dp[n-1];
    }

5 約瑟夫環

在這裏插入圖片描述
反推法

	public int lastRemaining(int n, int m) {
        int res=0;
        for(int i=2;i<=n;i++){
            res=(res+m)%i;
        }
        return res;
    }

棧和隊列

1 棧實現隊列

在這裏插入圖片描述

class CQueue {
    private Stack<Integer> s1;
    private Stack<Integer> s2;
    
    public CQueue() {
        s1=new Stack<>();
        s2=new Stack<>();
    }
    
    public void appendTail(int value) {
        s1.push(value);
    }
    
    public int deleteHead() {
        if(!s2.isEmpty())
            return s2.pop();
        if(!s1.isEmpty()){
            while(!s1.isEmpty()){
                s2.push(s1.pop());
            }
            return s2.pop();
        }
        return -1;
    }
  
}

2 包含min函數的棧

在這裏插入圖片描述

class MinStack {

    private Stack<Integer> s1=new Stack<>();
    private Stack<Integer> s2=new Stack<>();

    /** initialize your data structure here. */
    public MinStack() {

    }
    
    public void push(int x) {
        s1.push(x);
        if(s2.isEmpty()||x<=s2.peek())
            s2.push(x);
    }
    
    public void pop() {
        if(s1.peek().equals(s2.peek()))
            s2.pop();
        s1.pop();
    }
    
    public int top() {
        return s1.peek();
    }
    
    public int min() {
        return s2.isEmpty()?0:s2.peek();
    }
}

3 棧的壓入和彈出

在這裏插入圖片描述

public boolean validateStackSequences(int[] pushed, int[] popped) {
        Stack<Integer> stack=new Stack<>();
        int pushIndex=0;
        int popIndex=0;
        while(pushIndex!=pushed.length){
            stack.push(pushed[pushIndex]);
            while(!stack.isEmpty()&&stack.peek()==popped[popIndex]){
                stack.pop();
                popIndex++;
            }
            pushIndex++;
        }
        return stack.isEmpty();
    }


遞歸和循環

1 斐波那契數列

在這裏插入圖片描述

public int fib(int n) {
        if(n==0||n==1)
            return n;
        int[] arr=new int[n+1];
        arr[0]=0;
        arr[1]=1;
        for(int i=2;i<arr.length;i++)
            arr[i]=(arr[i-1]+arr[i-2])%1000000007;
        return arr[n];
    }

2 青蛙跳臺階問題

在這裏插入圖片描述

public int numWays(int n) {
        if(n==0||n==1)
            return 1;
        int[] arr=new int[n+1];
        arr[0]=1;
        arr[1]=1;
        for(int i=2;i<arr.length;i++)
            arr[i]=(arr[i-1]+arr[i-2])%1000000007;
        return arr[n];
    }

回溯法

1 機器人的運動範圍

在這裏插入圖片描述

	public int movingCount(int m, int n, int k) {
        boolean[][] visited=new boolean[m][n];
        return canReach(0,0,m,n,k,visited);
    }

    public int canReach(int i,int j,int m,int n,int k,boolean[][] visited){
        if(i==m||i<0||j==n||j<0||(i/10+i%10+j/10+j%10>k)||visited[i][j])
            return 0;
        visited[i][j]=true;
        return 1+canReach(i+1,j,m,n,k,visited)+canReach(i,j+1,m,n,k,visited)
                +canReach(i-1,j,m,n,k,visited)+canReach(i,j-1,m,n,k,visited);
    }

2 字符串的排列

在這裏插入圖片描述

class Solution {

    List<String> list=new ArrayList<>();
    char[] c;

    public String[] permutation(String s) {
        c=s.toCharArray();
        dfs(0);
        return list.toArray(new String[list.size()]);
    }

    public void dfs(int x){
        if(x==c.length-1){
            list.add(String.valueOf(c));
            return;
        }
        HashSet<Character> set=new HashSet<>();
        for(int i=x;i<c.length;i++){
            if(set.contains(c[i]))
                continue;
            set.add(c[i]);
            swap(x,i);
            dfs(x+1);
            swap(x,i);
        }

    }

    public void swap(int a,int b){
        char temp=c[a];
        c[a]=c[b];
        c[b]=temp;
    }
}

位運算

1 二進制1的個數

在這裏插入圖片描述

public int hammingWeight(int n) {
        int count=0;
        while(n!=0){
            count+=n&1;
            n=n>>>1;
        }
        return count;
    }

2 數組中數字出現的次數1

在這裏插入圖片描述

	public int[] singleNumbers(int[] nums) {
        int x=nums[0];
        for(int i=1;i<nums.length;i++)
            x=x^nums[i];
        int p=x&(-x);
        int[] arr=new int[2];
        for(int i=0;i<nums.length;i++){
            if((nums[i]&p)==p)
                arr[0]^=nums[i];
            else
                arr[1]^=nums[i];
        }
        return arr;
    }

3 數組中數字出現的次數2

在這裏插入圖片描述

	public int singleNumber(int[] nums) {
        HashMap<Integer,Integer> map=new HashMap<>();
        for(int n:nums){
            if(map.containsKey(n))
                map.put(n,map.get(n)+1);
            else
                map.put(n,1);
        }
        Set<Integer> integers = map.keySet();
        for(int i:integers){
            if(map.get(i)==1)
                return i;
        }
        return -1;
    }

4 計算1+2+…+n

在這裏插入圖片描述
短路與

public int sumNums(int n) {
        boolean help=n>1&&(n+=sumNums(n-1))>1;
        return n;
    }

5 不用加減乘除做加法

在這裏插入圖片描述

	public int add(int a, int b) {
        while(b!=0){
            int c=(a&b)<<1;
            a^=b;
            b=c;
        }
        return a;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章