leetcode刷題筆記[Easy1-25題]

  • Eg1.
    //①只有數組纔可以有length方法,鏈表不可
    // ②即使在內循環for有了return,主函數也要有return
class Solution {
    public int[] twoSum(int[] nums, int target) {
        int ans;
        for(int i = 0; i < nums.length; i ++){
            ans = target - nums[i];
            ***//①只有數組纔可以有length方法,鏈表不可***
            for(int j = i + 1; j < nums.length; j++){
                if(nums[j] == ans)
                    **return new int[] {i,j};**
            }
        }
        **return null;**	// ***②即使在內循環for有了return,主函數也要有return***
    }
}
  • Eg2.
    //②一個循環解決一個循環的問題,不要將上一個循環的值留到下一個循環來填寫
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        //以l1鏈爲默認鏈
        ListNode p, q;
        int temp, carry = 0;
        //此處for的判斷條件沒用
        for(p = l1, q = l2; p != null && q != null; p = p.next, q = q.next){
            //計算包括三部分:a、b、進位
            temp = p.val + q.val + carry ;
            //進位置0
            carry = 0;
            //如果有進位
            if(temp > 9){
                carry = 1;
                temp = temp % 10;
            }

            //判斷某個鏈表是不是到頭了,***①有三種情況***
            //如果兩個都到頭
            if(p.next == null && q.next == null){
                p.val = temp;
                if(carry == 1)
                    p.next = new ListNode(1);
                return l1;
            }
            if(p.next == null){
                p.val = temp;
                p.next = q.next;
                p = p.next;
                break;
            }       
            if (q.next == null) {
                p.val = temp;
                p = p.next;
                break;
            }

            //填數
            p.val = temp;
        }
        ***//②一個循環解決一個循環的問題,不要將上一個循環的值留到下一個循環來填寫***
        while(p.next != null){
            temp = p.val + carry;
            carry = 0;
            if(temp > 9){
                carry = 1;
                temp = temp % 10;
            }
            //填數
            p.val = temp;
            p = p.next;
        }
        //判斷最高位是否需要擴展
        temp = p.val + carry;
        if (temp > 9) {
            temp = temp % 10;
            p.next = new ListNode(1);
        }
        p.val = temp;
        return l1;
    }
}
  • Eg9.
    • 1.Line 10: error: cannot find symbol [in Driver.java]
      boolean ret = new Solution().isPalindrome(param_1);
      ^
      symbol: method isPalindrome(int)
      location: class Solution
      由於這道題是判斷迴文題,這個錯誤是說,你的函數名稱要用isPalindrome
      //①求整數的位數:循環,將除數不斷乘10,直至商爲個位數
      //②將number截取首位與尾位:求餘,再對餘數除以10
import java.lang.String;
class Solution{
   public boolean isPalindrome(int number){
        //負數統統不是迴文數
       if (number < 0)  
            return false;
       // 位數多於1的判斷
        //判斷數字的迴文性,循環取最高位與最低位
        //1.先求number的位數,temp1存的是number的數量級10 100 1000
       int temp1 = 1;
       int temp2 = number/temp1;
       int topNum = 0 , bottomNum = 0;
       //①求整數的位數:循環,將除數不斷乘10,直至商爲個位數
       while (temp2 >= 10){
           temp1 *= 10;
           temp2 = number / temp1;    
        }
       //循環取最高位與最低位
       //如果condition爲 number>=10,那麼就會分不清10011跟111這種情況,
       //上述這兩種情況區別在於他們的temp1存儲的數量級不同
       while (number > 0){
           //取首位跟尾位
           topNum = number / temp1;
           bottomNum = number % 10 ;
           if (topNum != bottomNum)
               return false;
           //②將number截取首位與尾位:求餘,再對餘數除以10
           number = number%temp1/10;
          // number = number / 10;
           temp1 /= 100;
        }
        
        return true;
   } 
}
  • Eg 13. 羅馬數字
    //①靜態函數只能調用靜態函數,故該子函數需要用static修飾
    //②由於switch內部語句是return,所以無需break
    //③遍歷String字符串,使用string.charAt(index),返回char
class Solution {

    public int romanToInt(String s) {
    
      int length = s.length();
      int pre = 65535, cur = 0;
      int sum = 0;
      char temp;
      //掃描
      for(int i = 0; i < length; i++){
      	***//③遍歷String字符串,使用string.charAt(index),返回char***
          temp = s.charAt(i);
          cur = invertInt(temp);
          if(pre >= cur)
            sum += cur;
          else
            sum = sum - 2*pre + cur;
          pre = cur;
      }
      
      return sum;

    }
   
    public int invertInt(char str){
        ***//②由於switch內部語句是return,所以無需break***
        switch (str){
            case 'I': 
              return 1; 
              //break;
            case 'V': 
              return 5;
             // break;
            case 'X': 
              return 10;
              //break;
            case 'L': 
              return 50;
             // break;
            case 'C': 
              return 100;
              //break;
            case 'D': 
              return 500;
             // break;
            case 'M': 
              return 1000;
             // break;
            default: 
              return -1;
        }
    }
}
  • Eg14. 最長公共子串
    Line 9: java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
    問題出現在:當這個數組爲空時,不能取下標爲0,而不是當下標爲0的元素爲空時不能取length
    //①當初出現的錯誤是minlen = strs[0].length()這個語句Index 0 out of bounds for length 0。所以問題出現在:當這個數組爲空時,不能取下標爲0,而不是當下標爲0的元素爲空時不能取length
    //②Java求字符串長度:String.length()
    //③Java求數組元素個數:String[].length;
import java.util.Arrays;
class Solution {
    public String longestCommonPrefix(String[] strs) {
        String comStr = "";
        if(strs.length == 0) return comStr;
        ***//①當初出現的錯誤是minlen = strs[0].length()這個語句Index 0 out of bounds for length 0
        //所以問題出現在:當這個數組爲空時,不能取下標爲0,而不是當下標爲0的元素爲空時不能取length***
       // if (Arrays.asList(strs).contains("")){
         //   return comStr;
        //}

        ***//②Java求字符串長度:String.length()
        //③Java求數組元素個數:String[].length;***
        int minlen = strs[0].length(), curlen;
        char curchar;
        //對數組進行遍歷,求數組最短元素的長度
        for (int i = 0 ; i < strs.length; i++) {
            curlen = strs[i].length();
            if (curlen < minlen) 
               minlen = curlen;        
        }
        //外層對首元素進行遍歷,遍歷次數爲最短元素的長度minlen
        for (int i = 0; i < minlen; i++) {
            curchar = strs[0].charAt(i);
            //內層對所有元素遍歷
            for (int j = 1; j < strs.length; j++) {
                if (curchar != strs[j].charAt(i))
                    return comStr;
            }
            comStr += curchar;
        }
        return comStr;
    }
}
  • Eg20.有效的括號
    //①注意此處s是字符串String型,故不能用數組取元素s[i]的方式
class Solution {
    public boolean isValid(String s) {
        if (s == "")  return true;
        int length = s.length(), rear = -1;
        char[] stack = new char[length];
        char temp;
        ***//①注意此處s是字符串String型,故不能用數組取元素s[i]的方式***
        for(int i = 0; i < length; i++) {
            if (s.charAt(i) == '(' || s.charAt(i) == '[' || s.charAt(i) == '{')
                stack[++rear] = s.charAt(i);
            if (s.charAt(i) == ')' || s.charAt(i) == ']' || s.charAt(i) == '}'){
                if (rear == -1)  return false;
                temp = stack[rear];
                if ((temp == '(' && s.charAt(i) == ')') || (temp == '[' && s.charAt(i) == ']') || (temp == '{' && s.charAt(i) == '}'))
                    rear--;
                else
                   return false;
            } 
        }
        if (rear >= 0)  return false;
        return true;

    }
}
  • Eg21.合併兩個鏈表
    //①Java中,p是class,condition不能直接是while(p&&q)
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    //思路:1.確定是要轉移結點還是複製結點,由於Java指針不方便使用,我選擇複製結點
    //2.確定有多少個指針:新鏈表頭指針、尾指針,l1、l2的運動指針,新節點的指針
    //3.新鏈表有結點時,與無結點時分別又是如何:有結點時要連接結點,更換尾指針;
    //無結點時頭指針跟尾指針都要指向新節點
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if (l1 == null) return l2;
        if (l2 == null) return l1;
        //由於下述需要用到list,r,n的判斷,所以要初始化
        ListNode list = null ;

        ListNode p = l1, q = l2, r = null, n = null;  //r指向新鏈表尾,n指向新的結點

        ***//①Java中,p是class,condition不能直接是while(p&&q)***
        while (p != null && q != null) {
            if (p.val <= q.val) {
                n = new ListNode(p.val, null);
                if (list == null) 
                    list = n;
                else 
                    r.next = n;
                r = n;
                p = p.next;
                
            }
            else {
                n = new ListNode(q.val, null);
                if (list == null)
                    list = n;
                else 
                    r.next = n;
                r = n;
                q = q.next;
            }
        }
        if (p != null) 
            r.next = p;
        if (q != null)
            r.next = q;
        return list;

    }
}
  • Eg26.刪除排序數組中的重複項
class Solution {
    public int removeDuplicates(int[] nums) { 
        //符合條件,新鏈表更改再移動j,否則僅僅移動j
        int i = 0, j = 1;
        while (j < nums.length) {
            if (nums[j] != nums[i]) {
                nums[i+1] = nums[j];
                i++;
            }
            j++;
        }
        return i+1}
}
  • Eg28. 查詢子字符串的位置
    調用String.indexOf()方法,若不存在,自動返回-1
class Solution {
    public int strStr(String haystack, String needle) {
        int index = haystack.indexOf(needle);
        return index;
    }
}
  • Eg38.外觀數列
    //①Java將char型轉換爲int型最簡單的方法是 int b = char - ‘0’ ;
    //即char隱式轉換成int型時,轉爲對應的ASCII值

    //②Java當int與char/String共同運算時,會自動轉換爲char/String
class Solution {
    public String countAndSay(int n) {
        if (n == 0)  return "";
        int i = 1;
        String res = "1";
        while (i < n) {
            res = getSay(res);
            i++;
        }
        return res;
    }
    public String getSay(String lastNum) {
        String res = "";
        int flag = 1, k = 0;    //flag標記當前字符是否與上一個字符相同;k計數連續的字符數;當flag=0時,k=0
        char curchar;
        int curnum;
        for (int i = 0; i < lastNum.length(); i++) {
            curchar = lastNum.charAt(i);    //當前數字字符
            curnum = curchar - '0';         //當前數字
            ***//①Java將char型轉換爲int型最簡單的方法是 int b = char - '0' ;
            //即char隱式轉換成int型時,轉爲對應的ASCII值***
            if (i == 0) 
                k++;
            else {
                if (curchar == lastNum.charAt(i-1) ) //如果字符連續相等
                    k ++ ;
                else{
                    ***//②Java當int與char/String共同運算時,會自動轉換爲char/String***
                    res = res + k + lastNum.charAt(i-1);
                    k = 1;
                }
            }
        }
        res = res + k + lastNum.charAt(lastNum.length()-1);
        return res;
    }
}
  • Eg53.最大子序和 (重做!!!)
    //找具有最大和的連續數組,即動態規劃問題(對應做兼職賺錢賺取最多的錢)。思路:求每一步的最優解,再求全局的最優解
    //每一步求當前的最大和:取(與上一步的最大和相加):sum=sum+nums[i]
    //不取(自身等於最大和):sum = nums[i]

    //①Java求最大值的函數:Math.max()
import java.util.*;
class Solution {
    public int maxSubArray(int[] nums) {
        //找具有最大和的連續數組,即動態規劃問題(對應做兼職賺錢賺取最多的錢)。思路:求每一步的最優解,再求全局的最優解
        //每一步求當前的最大和:取(與上一步的最大和相加):sum=sum+nums[i]
        //不取(自身等於最大和):sum = nums[i]

        if (nums.length == 0)   return 0;
        //數組dp存取每一步的最優解
        int[] dp = new int[nums.length];
        dp[0] = nums[0];
        int max = dp[0];
        for (int i = 1; i < nums.length; i++) {
            dp[i] = Math.max(dp[i-1] + nums[i], nums[i]);   
            max = Math.max(dp[i], max);
        }

        return max;
        
    }
}

-Eg58.最後一個單詞的長度
//①Java也有跟Python一樣的String.split()分割字符串的方法,但是要用字符號串數組存儲

class Solution {
    public int lengthOfLastWord(String s) {

        String[] strlist = s.split(" ");
        int listlen = strlist.length;
        if (listlen == 0)  return 0;
        int length = strlist[listlen-1].length();
        return length;
    }
}
  • Eg67.二進制求和
    //①Java char轉int型: char - ‘0’;
    //②Java int轉String型: Integer.String();
class Solution {
    public String addBinary(String a, String b) {
        int blen = b.length(), alen = a.length(), maxlen = Math.max(alen, blen);
        int  t1, t2, carry=0,temp;
        int deltalen = Math.abs(blen-alen);
        String s = "";
        if (blen > alen) 
            while ((deltalen--) > 0)
                a = "0" + a;
        else
            while ((deltalen--) > 0)
                b = "0" + b;
        
        for (int i = maxlen-1; i >= 0; i--) {
            t1 = b.charAt(i) - '0';
            t2 = a.charAt(i) - '0';
            temp = (t1 + t2 + carry) % 2;
            carry = (t1 + t2 + carry) / 2;
            s =  Integer.toString(temp) + s;
        }
        if (carry == 1)
            s = "1" + s ;
        return s;

    }
}
  • Eg70. 爬樓梯
    //爬樓梯問題:斐波拉契數列問題
    //特徵:每一步都可以化爲解決一步,剩下的小問題交給下一個人解決(移動磚頭問題)
    //此處:若要走n階臺階,需要兩步。第一步:走1個臺階,剩下的n-1步由n-1步走法決定(設爲afa步);
    //或者,第一步:走2個臺階,剩下的n-2步由n-2步走法決定(設爲beta步)。
    //所以走n步臺階,有總共afa+beta步
class Solution {

    public int climbStairs(int n) {
        int start1 = 1, start2 = 2;
        int temp = 0;
        if (n == 1) return start1;
        if (n == 2) return start2;
        for (int i = 3; i <= n; i++) {
            temp = start1 + start2;
            start1 = start2;
            start2 = temp;
        }
        return temp;
    }
}
  • Eg100 相同的樹.【重做】
    重點:結點爲空時,讓其值爲-65535,不爲空時,讓其值爲真實val。這樣會讓隊列遍歷方便很多
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean isSameTree(TreeNode p, TreeNode q) {

        //根節點相同的情況下
        TreeNode ptr = p, qtr = q;
        TreeNode[] l1 = new TreeNode[1000], l2 = new TreeNode[1000];
        
        int temp1, temp2, front1, front2, rear1, rear2;
        front1 = front2 = rear1 = rear2 = -1;
        l1[++rear1] = ptr;
        l2[++rear2] = qtr;

        int val1, val2;
        //用隊列層次遍歷樹,當隊列不空時,樹未遍歷結束
        while (front1!=rear1 && front2!=rear2) {
            //出隊列
            ptr = l1[++front1];
            qtr = l2[++front2];

            //彈出隊首結點。如果該節點不爲空,將其左右結點壓入隊列;如果爲空,僅僅彈出
            if (ptr == null)
                val1 = -65535;
            else {
                val1 = ptr.val;
                l1[++rear1] = ptr.left;
                l1[++rear1] = ptr.right;
            }
            if (qtr == null)
                val2 = -65535;
            else {
                val2 = qtr.val;
                l2[++rear2] = qtr.left;
                l2[++rear2] = qtr.right;
            }
            //如果結點不同,結束循環
            if (val1 != val2) 
                return false;
        }

        return true;
    }
}
  • Eg 101對稱二叉樹(重做)
    //該層所有元素出列後,判斷該層元素是否鏡像對稱,此時下一層元素也全部進隊列
    //當時出現的錯誤:對於用例[1,2,2,null,3,3,null]時,在遍歷第3層時,flag爲第2個null
    //當指針指向第一個null時,condition爲ptr(=null) == flag,誤以爲到了該層次結尾
    //edition2:由於我把null的情況用-65535來代替,所以我只需要計算出隊的結點數,判斷其是否等於層數
    //condition 爲(count+1) == (int)Math.pow(2,level-1)) 這個想法又錯了,問題出在空節點無法掛左右空節點
    //所以某層的總數不爲Math.pow(2,level-1)
    //所以要用incnt跟outcnt來對進出隊列計數
class Solution {
    public boolean isSymmetric(TreeNode root) {
        if (root == null)   return true;

        TreeNode ptr = root;
        TreeNode[] list = new TreeNode[1000];
        //outcnt計算該層出隊列的數,incnt計算該層進隊列的數,注意數字下標(outcnt)從1開始
        int front = -1, rear = -1, val, outcnt = 0, incnt = 1;  
        int[]  numarr = new int[1000];
        list[++rear] = ptr;

        while (front != rear) {
            ptr = list[++front];
            if (ptr == null)    val = -65535;
            else {
                val = ptr.val;
                list[++rear] = ptr.left;
                list[++rear] = ptr.right;
            }
            numarr[++outcnt] = val;         

            //該層所有元素出列後,判斷該層元素是否鏡像對稱,此時下一層元素也全部進隊列
            //當時出現的錯誤:對於用例[1,2,2,null,3,3,null]時,在遍歷第3層時,flag爲第2個null
            //當指針指向第一個null時,condition爲ptr(=null) == flag,誤以爲到了該層次結尾
            //edition2:由於我把null的情況用-65535來代替,所以我只需要計算出隊的結點數,判斷其是否等於層數
            //condition 爲(count+1) == (int)Math.pow(2,level-1)) 這個想法又錯了,問題出在空節點無法掛左右空節點
            //所以某層的總數不爲Math.pow(2,level-1)
            //所以要用incnt跟outcnt來對進出隊列計數
            if (outcnt == incnt){
                //注意數字下標(outcnt)從0開始
                for (int i = 1, j = outcnt; i < j; i++, j--) {
                    if (numarr[i] != numarr[j])
                        return false;                 
                }
                //如果該層鏡像對稱,重新set
                incnt = rear - front;
                outcnt = 0;
            }

        }
        return true;
    }
}

===========================
遞歸算法:

compare (leftNode, rightNode) { 
        if (leftNode != null && rightNode != null)  
            return leftNode.val == rightNode.val ? compare(leftNode.left, rightNode.right) && compare(leftNode.right, rightNode.left) : false;
         return leftNode == null && rightNode == null; 
}
  • Eg125(驗證迴文串)
    //①Java字符串用正則表達式時採用String.replaceAll();
    //②a比A多32
    //核心:將大寫字符全部轉爲小寫字符
class Solution {
    public boolean isPalindrome(String s) {

    	//①Java字符串用正則表達式時採用String.replaceAll();
    	//②a比A多32
        String str = s.replaceAll("[^a-zA-Z0-9]","");
        char left, right;
        for (int i=0, j=str.length()-1; i < j ;i++, j-- ) {
            left = str.charAt(i);
            right = str.charAt(j);
            if(left >= 'A' && left <= 'Z')
                left = (char)(left+32);
            if(right >= 'A' && right <= 'Z')
                right = (char)(right+32);
            if(left != right)
                return false;
                
        }

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