Leetcode算法代碼解答總結——長文慎入!(持續更新)

        ——寫在前面,複習算法一段時間了,在此記錄一下自己寫過的算法代碼,算是做個總結,供自己以後回顧。

43.字符串相乘

給定兩個以字符串形式表示的非負整數 num1 和 num2,返回 num1 和 num2 的乘積,它們的乘積也表示爲字符串形式。

示例 1:

輸入: num1 = "2", num2 = "3"
輸出: "6"

示例 2:

輸入: num1 = "123", num2 = "456"
輸出: "56088"

思路:大數相乘,用一個int數組存每一位的相乘數,像小學時學的乘法運算那樣算

class Solution {
    public String multiply(String num1, String num2) {
        if(num1.equals("0")||num2.equals("0"))
            return "0";
        int len1 = num1.length();
        int len2=num2.length();
        int res_len=len1+len2;
        int res[]=new int [res_len];
        for(int i=len1-1;i>=0;i--){
            int n1=num1.charAt(i)-48;
            int tmp=0;
            for(int j=len2-1;j>=0;j--){
                int n2=num2.charAt(j)-48;
                res[i+j+1]=n1*n2+res[i+j+1]+tmp;
                tmp =res[i+j+1]/10;
                res[i+j+1]=res[i+j+1]%10;
            }
            res[i]+=tmp;
        }
        StringBuilder sb=new StringBuilder();
        int flag=1;
        for(int i=0;i<res_len;i++){
            if(res[i]==0&&flag==1)
                continue;
            sb.append(res[i]);
            flag=0;
        }
        return sb.toString();
    }
}

322. 零錢兌換

給定不同面額的硬幣 coins 和一個總金額 amount。編寫一個函數來計算可以湊成總金額所需的最少的硬幣個數。如果沒有任何一種硬幣組合能組成總金額,返回 -1

class Solution {
    public int coinChange(int[] coins, int amount) {
        int size=coins.length;
        int dp[]=new int[amount+1];
        //0x3F3F3F表示一個很大的數,dp[j]表示找零金額爲j時的最少硬幣數
        Arrays.fill(dp,0x3F3F3F);
        dp[0]=0;
        //遍歷i種硬幣,新的最少硬幣數會覆蓋舊的最少硬幣數
        for(int i=0 ;i<size;i++){
            for(int j=coins[i];j<=amount;j++){ 
                //如果拿一個coins[i]硬幣,硬幣數就是dp[j-coins[i]]+1,但如果金額爲j-coins[i]不                           
                //能找零,則找零最少硬幣數爲0x3F3F3F+1,則最少硬幣還是dp[j](0x3F3F3F),歸根到底
                //還是不能找零
                dp[j]=Math.min(dp[j-coins[i]]+1,dp[j]);
            }
        }
        if(dp[amount]==0x3F3F3F)
            dp[amount]=-1;
        return dp[amount];
    }
}

62不同路徑

一個機器人位於一個 m x n 網格的左上角 (起始點在下圖中標記爲“Start” )。

機器人每次只能向下或者向右移動一步。機器人試圖達到網格的右下角(在下圖中標記爲“Finish”)。

問總共有多少條不同的路徑?

輸入: m = 3, n = 2
輸出: 3
解釋:
從左上角開始,總共有 3 條路徑可以到達右下角。
1. 向右 -> 向右 -> 向下
2. 向右 -> 向下 -> 向右
3. 向下 -> 向右 -> 向右

考察:dp動態規劃,dp[i][j]=dp[i-1][j]+dp[i][j-1]

class Solution {
    public int uniquePaths(int m, int n) {
        if(m==1&&n==1)
            return 1;
        int dp[][]=new int[m][n];
        for(int i=1;i<n;i++){  //行數爲1,只能橫着走,走法只有一種
            dp[0][i]=1;
        }
        for(int j=1;j<m;j++){  //列數爲1,只能豎着走,走法只有一種
           dp[j][0]=1;
        }
        for(int i=1;i<m;i++){
           for(int j=1;j<n;j++){
               dp[i][j]=dp[i-1][j]+dp[i][j-1];  //要麼從上面下來,要麼從左邊過來,走法爲這兩種情況之和
           }
        }
        return dp[m-1][n-1];
    }
}

 

69x 的平方根

實現 int sqrt(int x) 函數。

計算並返回 x 的平方根,其中 是非負整數。

由於返回類型是整數,結果只保留整數的部分,小數部分將被捨去。

示例 2:

輸入: 8
輸出: 2
說明: 8 的平方根是 2.82842..., 
     由於返回類型是整數,小數部分將被捨去。

考察:二分搜索

class Solution {
    public int mySqrt(int x) {
       int i=1,j=x;
       while(i<=j)
       {
           int mid=(i+j)/2;
           if(mid<x/mid)
               i=mid+1;
           else if(mid>x/mid)
               j=mid-1;
           else return mid;
       }
        return j;
    }
}
//另一種做法  return  (int)Math.sqrt(x);

94二叉樹的中序遍歷

給定一個二叉樹,返回它的中序 遍歷。

示例:

輸入: [1,null,2,3]
   1
    \
     2
    /
   3

輸出: [1,3,2]

考察:有兩種做法,遞歸很簡單,迭代複雜點

class Solution {
    List<Integer> res=new ArrayList<Integer>();
    public void  search(TreeNode root){  //這是遞歸做法
        if(root==null)
            return;
        if(root.left!=null)
           search(root.left);
        res.add(root.val);
        if(root.right!=null)
           search(root.right);
    }
    public List<Integer> inorderTraversal(TreeNode root) {
       search(root);
       return res;
    }
}

67二進制求和

給定兩個二進制字符串,返回他們的和(用二進制表示)。

輸入爲非空字符串且只包含數字 1 和 0

示例 1:

輸入: a = "11", b = "1"
輸出: "100"

考察:math,相加的進位

class Solution {
    public String addBinary(String a, String b) {
        int aLen=a.length()-1;
        int bLen=b.length()-1;
        int m=0;
        int n=0;
        StringBuilder res=new StringBuilder();//用數組來存結果也可以,然後把數組轉化爲String,最後如果有進位則在結果前加個"1"
        while(aLen>=0&&bLen>=0){
            int tmp=a.charAt(aLen)-'0'+b.charAt(bLen)-'0'+n;
            m=tmp%2;
            n=tmp/2;
            res.insert(0,String.valueOf(m));
            aLen--;
            bLen--;            
        }
        while(aLen>=0){
            int tmp=a.charAt(aLen)-'0'+n;
            m=tmp%2;
            n=tmp/2;
            res.insert(0,String.valueOf(m));
            aLen--;
        }
        while(bLen>=0){
            int tmp=b.charAt(bLen)-'0'+n;
            m=tmp%2;
            n=tmp/2;
            res.insert(0,String.valueOf(m));
            bLen--;
        }
        if(n>0){
            res.insert(0,"1");
        }
        return res.toString();
    }
}

 

49字母異位詞分組

給定一個字符串數組,將字母異位詞組合在一起。字母異位詞指字母相同,但排列不同的字符串。

示例:

輸入: ["eat", "tea", "tan", "ate", "nat", "bat"],
輸出:
[
  ["ate","eat","tea"],
  ["nat","tan"],
  ["bat"]
]

考察:HashMap

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
        Map<String,List<String>>map=new HashMap<>();
        List<List<String>>result=new ArrayList<>();
        if(strs.length==0)
            return result;
        for(String s:strs){
            char[] tmp=s.toCharArray();
            Arrays.sort(tmp);
            String keyStr=new String(tmp);
            if(!map.containsKey(keyStr))
            {
                List<String> item=new ArrayList<String>();
                item.add(s);
                map.put(keyStr,item);
                result.add(item);
            }
            else
               map.get(keyStr).add(s);
        }
        return result;
    }
}

 

206反轉鏈表

反轉一個單鏈表。

示例:

輸入: 1->2->3->4->5->NULL
輸出: 5->4->3->2->1->NULL

考察:遞推遍歷鏈表

/**
 * 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 cur=head.next;
        ListNode next;
        head.next=null;
        while(cur!=null){
            next=cur.next;
            cur.next=head;
            head=cur;
            cur=next;
        }
        return head;
    }
}

 

23合併K個排序鏈表

合併 個排序鏈表,返回合併後的排序鏈表。請分析和描述算法的複雜度。

示例:

輸入:
[
  1->4->5,
  1->3->4,
  2->6
]
輸出: 1->1->2->3->4->4->5->6

考察:兩指針,歸併

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode mergeTwoList(ListNode first,ListNode two){
        if(first==null)
            return two;
        if(two==null)
            return first;
        ListNode node=new ListNode(0);
        if(first.val<two.val){
            node.val=first.val;
            node.next=mergeTwoList(first.next,two);
        }
        else{
            node.val=two.val;
            node.next=mergeTwoList(first,two.next);
        }
        return node;
    }
    public ListNode mergeKLists(ListNode[] lists) {
        if(lists==null||lists.length==0)
            return null;
        else if(lists.length==1)
            return lists[0];
        else{
            int begin=0,end=lists.length-1;
            while(end>0){
                begin=0;
                while(begin<end){
                    lists[begin]=mergeTwoList(lists[begin],lists[end]);
                    begin++;
                    end--;
                }
            }
            return lists[0];
        }
    }
}

24兩兩交換鏈表中的節點

給定一個鏈表,兩兩交換其中相鄰的節點,並返回交換後的鏈表。

示例:

給定 1->2->3->4, 你應該返回 2->1->4->3.

考察:鏈表

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode swapPairs(ListNode head) {
        if(head==null||head.next==null)
            return head;
        ListNode second=head.next;
        ListNode third=second.next;
        second.next=head;
        head.next=swapPairs(third);
        return second;
    }
}

 

98、驗證是否是二叉搜索樹:給定一個二叉樹,判斷其是否是一個有效的二叉搜索樹。

考察:二叉搜索樹的中序遍歷是遞增(或遞減)的,通過遞歸進行中序遍歷

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    boolean isFirst=true;
    int lastval;
    public boolean isValidBST(TreeNode root) {
       if(root ==null){
           return true;
       }
       if(!isValidBST(root.left)){
           return false;
       }
       if(!isFirst&&lastval>=root.val)
           return false;
       isFirst=false;
       lastval=root.val;
       if(!isValidBST(root.right)){
           return false;
       }
       return true;
    }
}

22括號生成

給出 n 代表生成括號的對數,請你寫出一個函數,使其能夠生成所有可能的並且有效的括號組合。

例如,給出 = 3,生成結果爲:

[
  "((()))",
  "(()())",
  "(())()",
  "()(())",
  "()()()"
]

考察:深度優先搜索(dfs),棧,括號匹配

class Solution {
    int left,right; //分別記錄'('和')'的剩餘數量
    LinkedList <Character> stack=new LinkedList<>(); //棧,存儲左括號'('
    char item[]; //記錄每種情況的括號排列
    int len;
    List<String> result=new LinkedList<>();
    public void dfs(int depth){
        if(depth==len-1){  //遍歷到最後一個括號,一定是')'
            item[len-1]=')';
            String tmp=new String(item);
            result.add(tmp);
        }
        else {
            if(left!=0){
                stack.addFirst('(');
                item[depth]='(';
                left--;
                dfs(depth+1);
                left++;//回溯
                stack.poll();
            }
            if(right!=0&&!stack.isEmpty()){  //當')'剩餘數不爲0且棧中有'('時,可以取出一個左括號匹配
                stack.poll();
                item[depth]=')';
                right--;
                dfs(depth+1);
                right++; //回溯
                stack.addFirst('(');
            }
        }
    }
    public List<String> generateParenthesis(int n) {
        left=n-1;
        right=n;
        len=2*n;
        item=new char[n*2];
        item[0]='(';
        stack.addFirst('(');
        dfs(1);
        return result;
    }
}

 

127. 單詞接龍

給定兩個單詞(beginWord 和 endWord)和一個字典,找到從 beginWord 到 endWord 的最短轉換序列的長度。轉換需遵循如下規則:

  1. 每次轉換隻能改變一個字母。
  2. 轉換過程中的中間單詞必須是字典中的單詞。

說明:

  • 如果不存在這樣的轉換序列,返回 0。
  • 所有單詞具有相同的長度。
  • 所有單詞只由小寫字母組成。
  • 字典中不存在重複的單詞。
  • 你可以假設 beginWord 和 endWord 是非空的,且二者不相同。

考察:廣度優先搜索,最短路徑,注意:set的查找速度比list快很多

class Solution {
    public int ladderLength(String beginWord, String endWord, List<String> wordList) {
        if(!wordList.contains(endWord))
            return 0;
        int level=1,curnum=1,nextnum=0;
        LinkedList<String>q=new LinkedList<String>();
        Set<String>visited=new HashSet<String>();
        q.add(beginWord);
        visited.add(beginWord);
        Set dic=new HashSet(wordList);
        while(!q.isEmpty()){
           String str=q.poll();
           curnum--;           
           int len=str.length();
            for(int i=0;i<len;i++){
                char[]word=str.toCharArray();
                for(char j='a';j<='z';j++){
                   word[i]=j;
                   String tmp=new String(word);
                    if(tmp.equals(endWord)){
                       return level+1;
                    }
                    if(dic.contains(tmp)&&!visited.contains(tmp)){
                       q.add(tmp);
                       nextnum++;
                       visited.add(tmp);
                    }
                }
            }
            if(curnum==0){
               level++;
               curnum=nextnum;
               nextnum=0;
            }
        }
        return 0;
    }
}

12、實現strStr():

給定一個 haystack 字符串和一個 needle 字符串,在 haystack 字符串中找出 needle 字符串出現的第一個位置 (從0開始)。如果不存在,則返回  -1

考察:KMP算法

class Solution {

    public int strStr(String haystack, String needle) {

        char []nee=needle.toCharArray();
        char []hay=haystack.toCharArray();
        int l1=hay.length;
        int l2=nee.length;
        if(l2==0)
            return 0;
        int next[]=new int[l2];
        next[0]=-1;//計算next[]數組,當沒有公共前後綴時,next[i]=-1;
        for(int i=1;i<l2;i++){
           int t=next[i-1];
           while(nee[t+1]!=nee[i]&&t>=0) 
               t=next[t];
           if(nee[t+1]==nee[i])
               next[i]=t+1;
           else
               next[i]=-1;
        }
        int i=0,j=0;//遍歷查找,時間複雜度爲m+n
        while(i<l1){
           if(hay[i]==nee[j]){
               i++;j++;
               if(j==l2)
                   return i-l2;
           }
           else{
               if(j==0)
                   i++;
               else{
                   j=next[j-1]+1;
               }
           }
        }
        return -1;
    }
}

 

12整數轉羅馬數字

羅馬數字包含以下七種字符: I, V, X, LCD 和 M

例如, 羅馬數字 2 寫做 II ,即爲兩個並列的 1。12 寫做 XII ,即爲 X + II 。 27 寫做  XXVII, 即爲 XX + V + II 。

給定一個整數,將其轉爲羅馬數字。輸入確保在 1 到 3999 的範圍內。

考察:二維數組,math,指針遍歷字符串。

class Solution {
    public String intToRoman(int num) {
        String str=String.valueOf(num);
        String [][] arr={{"I","II","III","IV","V","VI","VII","VIII","IX"},
                       {"X","XX","XXX","XL","L","LX","LXX","LXXX","XC"},
                       {"C","CC","CCC","CD","D","DC","DCC","DCCC","CM"},
                       {"M","MM","MMM"}
                      };
        int len=str.length();
        StringBuilder sb=new StringBuilder();
        for(int i=0;i<len;i++){
            int tmp=str.charAt(i)-'0';
            String out;
            if(tmp==0)
                continue;
            if(len-i==4){
                out=arr[3][tmp-1];
                sb.append(out);
            }
            else if(len-i==3){
                out=arr[2][tmp-1];
                sb.append(out);
            }
            else if(len-i==2){
                out=arr[1][tmp-1];
                sb.append(out);
            }
            else{
                sb.append(arr[0][tmp-1]);
            }
        }
        return sb.toString();
    }
}

13羅馬數字轉整數

羅馬數字包含以下七種字符:I, V, X, LCD 和 M

給定一個羅馬數字,將其轉換成整數。輸入確保在 1 到 3999 的範圍內。

考察:swich分支,math

class Solution {
    public int romanToInt(String s) {
        int index[]={1,5,10,50,100,500,1000};
        char[] arr=s.toCharArray();
        int len=arr.length;
        int last=index[getIndex(arr[0])];
        int result=0;
        if(len==1)
            return last;
        int tmp=0;
        for(int i=1;i<len;i++){
            tmp=index[getIndex(arr[i])];
            if(last<tmp)
                result-=last;
            else result+=last;
            last=tmp;
        }
        result+=tmp;
        return result;
    }
    public int getIndex(char x){
        switch(x){
                case 'I' :return 0;
                case 'V' :return 1;
                case 'X' :return 2;
                case 'L' :return 3;
                case 'C' :return 4;
                case 'D' :return 5;
                case 'M' :return 6;
            default: return -1;
        }
    }
}

 

125. 驗證迴文串

給定一個字符串,驗證它是否是迴文串,只考慮字母和數字字符,可以忽略字母的大小寫。

考察:兩指針

class Solution {
    public boolean isPalindrome(String s) {
        if(s==null||s.length()==0)
            return true;
        s=s.toLowerCase();
        int len=s.length();
        char[] arr=new char[len];
        int j=0;
        for(int i=0;i<len;i++){
            char tmp=s.charAt(i);
            if(tmp>='a'&&tmp<='z'||tmp>='0'&&tmp<='9')
                arr[j++]=tmp;
        }
        int low=0,high=j-1;
        while(low<high){
            if(arr[low]==arr[high])
            {
                low++;
                high--;
            }
            else
                return false;
        }
        return true;
    }
}

 

88. 合併兩個有序數組

 

給定兩個有序整數數組 nums1 和 nums2,將 nums2 合併到 nums1 中,使得 num1 成爲一個有序數組。

考察:兩指針,歸併,歸併排序的歸併部分思路

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int []asis=new int[m];//輔助數組,把nums1中的m個數拷貝出來
        for(int i=0;i<m;i++){
           asis[i]=nums1[i];
        }
        int a=0,b=0;//a,b爲兩個指向nums1和nums2開頭的指針
        int i=0;
        while(i<m+n){
            if(a==m)//nums1中沒數據了
                nums1[i++]=nums2[b++];
            else if(b==n) //nums2中沒數據了
                nums1[i++]=asis[a++];
            else if(asis[a]<nums2[b]){
                nums1[i++]=asis[a++];  //nums1的數比nums2的數小
            }
            else {
                nums1[i++]=nums2[b++];  //nums2的數小
            }
        }
    }
}

 

73、矩陣置零

 

給定一個 m x n 的矩陣,如果一個元素爲 0,則將其所在行和列的所有元素都設爲 0。請使用原地算法

考察:數組,先標記再最後置零

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

27移除元素

給定一個數組 nums 和一個值 val,你需要原地移除所有數值等於 val 的元素,返回移除後數組的新長度。

考察:快排中swap的部分

class Solution {
    public int removeElement(int[] nums, int val) {
        int len=nums.length;
        int right=len-1;
        int i=0;
        while(i<=right){
            if(nums[i]==val){
                nums[i]=nums[right--];
            }
            else i++;
        }
        return right+1;
    }
}

 

16、有效的數字:

驗證給定的字符串是否爲數字。

例如:
"0" => true
" 0.1 " => true
"abc" => false
"1 a" => false

"2e10" => true

考察:math,一個數字是否合法,指針遍歷字符串,細節

class Solution {
    public boolean isNumber(String s) {
        s=s.trim();
        int len=s.length();
        if(len==0||s==null)
            return false;
        int i=0;
        boolean hasDot=false;
        boolean hasE=false;
        boolean hasDigit=false;
        if(s.charAt(i)=='e'||s.charAt(len-1)=='e'||s.charAt(len-1)=='+'||s.charAt(len-1)=='-')
            return false;
        if(s.charAt(i)=='-'||s.charAt(i)=='+'){
            i++;
        }
        while(i<len){
           if(s.charAt(i)>='0'&&s.charAt(i)<='9'){
               i++;
               hasDigit=true;
           }
           else if(s.charAt(i)=='e'&&hasE==false&&hasDigit==true){
               i++;
               hasE=true;
               if(s.charAt(i)=='+'||s.charAt(i)=='-'){
                   i++;
               }
           }
           else if(s.charAt(i)=='.'&&hasDot==false&&hasE==false){
               i++;
               hasDot=true;
           }
           else return false;
        }
        if(hasDigit==false)
            return false;
        return true;
    }
}

1、給定一個沒有重複數字的序列,返回其所有可能的全排列。

考察:深度優先搜索(dfs)

class Solution {
    int []visit;
    List<List<Integer>> result;
    int len;
    int [] Allnums;
    int [] result_arr;
    void dfs(int depth){
    	if(depth==len){
    		List <Integer> item=new ArrayList<>();
    		int arrLen=result_arr.length;
    		for(int j=0;j<arrLen;j++){
    			item.add(result_arr[j]);
    		}
    		result.add(item);
    	}
    	else{
    		for(int i=0;i<len;i++){
    			if(visit[i]==0){
    				result_arr[depth]=Allnums[i];
    				visit[i]=1;
    				dfs(depth+1);
    				visit[i]=0;
    			}
    		}
    	}
    }
    public List<List<Integer>> permute(int[] nums) {
        Allnums=nums;
    	result=new ArrayList<>();
        len=nums.length;
        result_arr=new int[len];
        visit=new int[len];
        dfs(0);
        return result;
    }
}

2、給定一個可包含重複數字的序列,返回所有不重複的全排列。

考察:深度優先搜索(dfs)

class Solution {
     int [] input;
	 int len;
	 int [] result;
	 List <List<Integer>> output;
	 Map<Integer, Integer> map;
	 Set<Integer> set;
	 int keylen;
	 void dfs(int depth){
		if(depth==len){
			List<Integer> AddToOutput=new ArrayList<Integer>();
			for(int k=0;k<len;k++){
				AddToOutput.add(result[k]);
			}
		    output.add(AddToOutput);
		    return;
		}
        for(int i=0;i<keylen;i++){
        	int value=map.get(input[i]);
        	if(value>=1){
        		result[depth]=input[i];
        		map.put(input[i], value-1);
        		dfs(depth+1);
        		map.put(input[i], value);

        	}
        }
	}


    public List<List<Integer>> permuteUnique(int[] nums) {
    	len=nums.length;
    	map=new HashMap<Integer, Integer>();
    	for(int i=0;i<len;i++){
    		if(map.get(nums[i])==null){
    			map.put(nums[i], 1);
    		}
    		else{
    			int tmp=map.get(nums[i]);
    			map.put(nums[i],tmp+1);
    		}
    	}
    	set=map.keySet();
    	keylen=set.size();
    	input=new int[keylen];
    	Iterator<Integer>it=set.iterator();
    	int cnt=0;
    	while(it.hasNext()){
    		input[cnt++]=it.next();
    	}
    	result=new int[len];
    	output=new ArrayList<>();
        dfs(0);
        return output;
    }
}

3、求最大子序和:給定一個整數數組 nums ,找到一個具有最大和的連續子數組(子數組最少包含一個元素),返回其最大和。

考察:動態規劃

class Solution {
    public int maxSubArray(int[] nums) {
       int len=nums.length;
       int []sum=new int[len];
       int []maxsubsum=new int[len];
       sum[0]=nums[0];
       maxsubsum[0]=nums[0];
        for(int i=1;i<len;i++){
           if(sum[i-1]<0)
               sum[i]=nums[i];
            else{
               sum[i]=sum[i-1]+nums[i];
            }
        }
        for(int i=1;i<len;i++){
            maxsubsum[i]=Math.max(maxsubsum[i-1],sum[i]);
        }
        return maxsubsum[len-1];
    }
}

 

5、二叉樹的層次遍歷

考察:廣度優先搜索(bfs)

/**
 * 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) {
        LinkedList <TreeNode> q=new LinkedList<TreeNode>();
        List <List<Integer>> result=new LinkedList<>();
        if(root==null)
            return result;
        List <Integer> first=new LinkedList<Integer>();
        first.add(root.val);
        result.add(first);               
        q.offer(root);      
        int curnum=1;
        int nextnum=0;
        List <Integer> item=new LinkedList<Integer>();
        while(!q.isEmpty()){
            TreeNode t=q.poll();
            curnum--;
            if(t.left!=null){
                item.add(t.left.val);
                q.offer(t.left);
                nextnum++;
            }
            if(t.right!=null){
                item.add(t.right.val);
                q.offer(t.right);
                nextnum++;
            }
            if(curnum==0){
               curnum=nextnum;
               nextnum=0;
               if(!item.isEmpty())
               {
                   result.add(item);
                   item=new LinkedList<Integer>();
               }                
            }

        }
        return result;
    }
}

6、合併區間:給出一個區間的集合,請合併所有重疊的區間

考察:排序(快速排序),歸併思路

/**
 * Definition for an interval.
 * public class Interval {
 *     int start;
 *     int end;
 *     Interval() { start = 0; end = 0; }
 *     Interval(int s, int e) { start = s; end = e; }
 * }
 */

class Solution {
    public void quickSort(Interval[] input,int low,int high){
         if(low>=high)
             return ;
         int v=input[low].start;
         int left=low,right=high;
         int i=low+1;
         while(i<=right){
            int tmp=input[i].start;
            if(tmp>v){
                Interval tmp2=input[i];
                input[i]=input[right];
                input[right--]=tmp2;
            }
            else if(tmp<v){
                Interval tmp2=input[i];
                input[i]=input[left];
                input[left++]=tmp2;
            }
            else i++;
         }
         quickSort(input,low,left-1);
         quickSort(input,right+1,high);
    }
    public List<Interval> merge(List<Interval> intervals) {
         List<Interval> res=new ArrayList<Interval>();     
         int len=intervals.size();
         if(len==0)
             return res;
         Interval [] input= new Interval[len];
         intervals.toArray(input);
         quickSort(input,0,len-1);
         Interval item=input[0];
         for(int i=1;i<input.length;i++){
        	Interval tmp=input[i];
        	if(tmp.start>item.end)
        		{
        		  res.add(item);
        		  item=tmp;
        		}
        	else{
        		item.end=Math.max(item.end, tmp.end);
        	}
        }
        res.add(item);
        return res;
    }
}

7、插入區間:

給出一個無重疊的 ,按照區間起始端點排序的區間列表。

在列表中插入一個新的區間,你需要確保列表中的區間仍然有序且不重疊(如果有必要的話,可以合併區間)。

考察:歸併思路

/**
 * Definition for an interval.
 * public class Interval {
 *     int start;
 *     int end;
 *     Interval() { start = 0; end = 0; }
 *     Interval(int s, int e) { start = s; end = e; }
 * }
 */
class Solution {
    public List<Interval> insert(List<Interval> intervals, Interval newInterval) {
        List<Interval> res=new ArrayList<Interval>();
        int len=intervals.size();
        if(len==0){
            res.add(newInterval);
            return res;
        }
        int l=newInterval.start;
        int r=newInterval.end;
        boolean insert=false;
        for(int i=0;i<len;i++){
            Interval tmp=intervals.get(i);
            if(tmp.start<=l&&tmp.end>=l)
                l=tmp.start;
            if(tmp.start<=r&&tmp.end>=r)
            {
                r=tmp.end;
                continue;
            }
            if(tmp.start>r&&!insert){
               res.add(new Interval(l,r));
               insert=true;
            }
            if(tmp.start>r||tmp.end<l)
               res.add(tmp);
        }
        if(!insert)
            res.add(new Interval(l,r));
        return res;
    }
}

8、無重複字符的最大字串:給定一個字符串,找出不含有重複字符的最長子串的長度

考察:哈希,ascii

class Solution {
    public int lengthOfLongestSubstring(String s) {
            int [] hash=new int[256];
        	Arrays.fill(hash, -1);
        	int maxLen=0,left=-1;
        	int len=s.length();
        	for(int i=0;i<len;i++){
        	   left=Math.max(left, hash[s.charAt(i)]);
        	   hash[s.charAt(i)]=i;
        	   maxLen=Math.max(maxLen, i-left);
        	}
            return maxLen;
    }
}

9、字符串轉整數:實現 atoi,將字符串轉爲整數。

考察:指針遍歷字符串的每個字符,math

class Solution {
    public int myAtoi(String str) {
        if(str.isEmpty())
            return 0;
        int flag=1,result=0,i=0,len=str.length();
        while(i<len&&str.charAt(i)==' ') i++;
        if(str.charAt(i)=='+'||str.charAt(i)=='-')
            flag=(str.charAt(i++)=='+')?1:-1;
        while(i<len&&str.charAt(i)>='0'&&str.charAt(i)<='9'){
            if(result>Integer.MAX_VALUE/10||(result==Integer.MAX_VALUE/10&&str.charAt(i)>'7'))
                return (flag==1)?Integer.MAX_VALUE:Integer.MIN_VALUE;
            result=result*10+(str.charAt(i++)-'0');
        }        
        return flag*result;
    }
}

10、三數之和:

給定一個包含 n 個整數的數組 nums,判斷 nums 中是否存在三個元素 a,b,c ,使得 a + b + c = 0 ?找出所有滿足條件且不重複的三元組。

注意:答案中不可以包含重複的三元組。

考察:2個指針設定,排序

class Solution {

    public List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>>result=new LinkedList<>();
        int len=nums.length;
        Arrays.sort(nums);
        for(int i=0;i<len-2;i++){
            if(i>0&&nums[i]==nums[i-1])
                continue;
            int a=nums[i];
            int left=i+1;
            int right=len-1;
            while(left<right){
                if(left>i+1&&nums[left]==nums[left-1])
                    left++;
                else if(a+nums[left]+nums[right]>0){
                    right--;
                }
                else if(a+nums[left]+nums[right]<0){
                    left++;
                }
                else{
                    List<Integer>item=new LinkedList<>();
                    item.add(nums[i]);
                    item.add(nums[left]);
                    item.add(nums[right]);
                    result.add(item);
                    left++;
                    right--;
                }
            }
        }
        return result;
    }
}

11、有效的括號:

給定一個只包括 '('')''{''}''['']' 的字符串,判斷字符串是否有效。

考察:棧

class Solution {
    public boolean isValid(String s) {
        LinkedList<Character> stack=new LinkedList<Character>();
        int len=s.length();
        for(int i=0;i<len;i++){
            Character c=s.charAt(i);
            if(c=='('||c=='{'||c=='['){
                stack.addFirst(c);
            }
            else{
                if(stack.isEmpty())
                    return false;
                Character top=stack.poll();
                if((c==')'&&top!='(')||(c=='}'&&top!='{')||(c==']'&&top!='['))
                    return false;
            }
        }
        return stack.isEmpty();
    }
}

 

13、合併兩個有序鏈表:

將兩個有序鏈表合併爲一個新的有序鏈表並返回。新鏈表是通過拼接給定的兩個鏈表的所有節點組成的。 

示例:

輸入:1->2->4, 1->3->4
輸出:1->1->2->3->4->4

考察:遞歸,歸併思路

/**
 * 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) {
        ListNode res=new ListNode(0);
        if(l1==null&&l2==null)
            return null;
        else if(l1!=null&&l2!=null){
            if(l1.val<l2.val){
                res.val=l1.val;
                res.next=mergeTwoLists(l1.next,l2);
            }
            else {
                res.val=l2.val;
                res.next=mergeTwoLists(l1,l2.next);
            }
        }
        else if(l1==null&&l2!=null){
            res.val=l2.val;
            res.next=l2.next;
        }
        else{
            res.val=l1.val;
            res.next=l1.next;
        }
        return res;
    }
}

2、兩數相加:

 

給定兩個非空鏈表來表示兩個非負整數。位數按照逆序方式存儲,它們的每個節點只存儲單個數字。將兩數相加返回一個新的鏈表。

你可以假設除了數字 0 之外,這兩個數字都不會以零開頭。

示例:

輸入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
輸出:7 -> 0 -> 8
原因:342 + 465 = 807

考察:遞歸

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode add(ListNode l1,ListNode l2,int jin){
        if(l1==null&&l2==null&&jin==0)
            return null;
        if(l1==null)
            l1=new ListNode(0);
        if(l2==null)
            l2=new ListNode(0);
        ListNode res=new ListNode(0);
        int sum=l1.val+l2.val+jin;
        res.val=sum%10;
        res.next=add(l1.next,l2.next,sum/10);
        return res;
    }
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
       return add(l1,l2,0);
    }
}

15、Pow(x,n):

實現 pow(xn) ,即計算 x 的 n 次冪函數。

考察:分治,把線性複雜度將爲logn

class Solution {
    public double myPow(double x, int n) {
        double res=1.0;
        if(x==0)
            return 0;
        else if(n==-1)
            return 1.0/x;
        else if(n==1)
            return x;
        else if(n==0)
            return 1.0;
        else {
            for(int i=n;i!=0;i/=2,x*=x){
                if(i%2!=0)
                    res*=x;
            }
            return n<0?1.0/res:res;
        }
        
    }
}

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章