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

你可能感兴趣的:(leetcode)