• [leetcode] 题解记录 1-10


    博客园markdown太烂, 题解详见https://github.com/TangliziGit/leetcode/blob/master/solution/1-10.md

    Leetcode Solution 0~10

    marks:
    @: hard to get a direct solution
    %: need optimization

    好题

    @@@@@ 4. Median of Two Sorted Arrays [Hard]
    % 5. Longest Palindromic Substring [Medium]
    @ 10. Regular Expression Matching [Hard]

    总结

    1. map用法: put, get, containsKey, remove
    2. 声明数组new int[]{1, 2};
    3. 异常情况还需要返回值的话, 抛IllegalArgumentException
    4. Set的用法: add, contains, remove
    5. 数组填充: Arrays.fill(arr, -1);
    6. java中有int的最大值, Integer.MAX_VALUE
    7. int+String的形式可以进行运算, 因为自动装箱(auto-boxing)
    8. StringBuilder用法: append, toString
    9. 反转字符串需要StringBuilder.reverse()
    10. 利用java对象默认值是null, 可以避免初始化
    11. 事实上java基本类型中的数值默认值都是0, char的默认值是'u0000'是空字符

    1. Two Sum [Easy]

    1. Two Sum [Easy]

    思路

    水题

    要点

    1. map用法: put, get, containsKey, remove
    2. 声明数组new int[]{1, 2};
    3. 异常情况还需要返回值的话, 抛IllegalArgumentException

    代码

    class Solution {
        public int[] twoSum(int[] nums, int target) {
            Map<Integer, Integer> map=new HashMap();
            
            for (int i=0; i<nums.length; i++){
                int tmp=target-nums[i];
                if (map.containsKey(tmp)){
                    int idx=map.get(tmp);
                    if (i!=idx) return new int[]{idx, i};
                }map.put(nums[i], i);
            }
            throw new IllegalArgumentException();
        }
    }
    
    2. Add Two Numbers [Medium]

    2. Add Two Numbers [Medium]

    思路

    水题

    要点

    代码

    class Solution {
        public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
            ListNode head=null, tail=null, prev=null;
            int tmp=0;
            while (l1!=null || l2!=null || tmp!=0){
                int val=(tmp+ 
                     ((l1!=null)?l1.val:0) + 
                     ((l2!=null)?l2.val:0)
                );
                tail=new ListNode(val%10);
                tmp=val/10;
                
                if (prev==null) head=tail;
                if (prev!=null) prev.next=tail;
                prev=tail;
                if (l1!=null) l1=l1.next;
                if (l2!=null) l2=l2.next;
            }
            
            return head;
        }
        
    }
    
    3. Longest Substring Without Repeating Characters [Medium]

    3. Longest Substring Without Repeating Characters [Medium]

    思路

    双指针

    要点

    1. Set的用法: add, contains, remove
    2. 数组填充: Arrays.fill(arr, -1);

    代码

    class Solution {
        public int lengthOfLongestSubstring(String s) {
            int[] map=new int[128];
            int pre=0, pos=0, maxlen=0, len=s.length();
            
            Arrays.fill(map, -1);
            for (int i=0; i<len; i++){
                char ch=s.charAt(i);
                if (map[ch]>=pos) pos=map[ch]+1;
                map[ch]=i;
                
                pre++;
                maxlen=Math.max(maxlen, pre-pos);
            }return maxlen;
        }
    }
    
    
    4. Median of Two Sorted Arrays [Hard]

    @@@@@ 4. Median of Two Sorted Arrays [Hard]

    思路

    非常好的一道题

    1. 第一个思路是二分中位数, 同时树状数组查小于此数的数字个数, 当等于(n+m)/2时就是中位数, 这样O(log^2(n+m))
      但想到没有给数据范围, 于是树状数组不太好直接存数, 得离散化然后存, 不然数组可能开不下

    2. 第二个思路是二分中位数, 同时二分两个数组查小于此数的数字个数, 当等于(n+m)/2时就是中位数, 这样O(log(n+m)(log(n)+log(m)))
      优点是不用离散化, 但同时复杂度更差了

    3. 题解思路:

    • 首先考虑寻找第k个数的算法, 那么中位数就是他俩除二
    • 其次考虑每次寻找各序列中aMid=a[i+k/2-1]这个数
      若aMid<bMid, 说明a中[0, aMid]和[bMid, m-1]之间是没有第k值的
      显然可以分治

    要点

    1. java中有int的最大值, Integer.MAX_VALUE
    2. int+String的形式可以进行运算, 因为自动装箱(auto-boxing)

    代码

    class Solution {
        private int[] a, b;
        
        public double findMedianSortedArrays(int[] nums1, int[] nums2) {
            this.a=nums1; this.b=nums2;
            int n=nums1.length, m=nums2.length;
            
            if (n==0 && m==0) return 0;
            int left=findKth(0, 0, (n+m-1)/2+1), right=findKth(0, 0, (n+m)/2+1);
            return (left+right)/(double)2;
        }
        
        public int findKth(int ai, int bi, int k){
            if (bi>=b.length) return a[ai+k-1];
            if (ai>=a.length) return b[bi+k-1];
            if (k==1) return Math.min(a[ai], b[bi]);
            
            int aMid=Integer.MAX_VALUE, bMid=Integer.MAX_VALUE;
            if (ai+k/2-1<a.length) aMid=a[ai+k/2-1];
            if (bi+k/2-1<b.length) bMid=b[bi+k/2-1];
            
            if (aMid<bMid)
                return findKth(ai+k/2, bi, k-k/2);
            else return findKth(ai, bi+k/2, k-k/2);
        }
    }
    
    5. Longest Palindromic Substring [Medium]

    % 5. Longest Palindromic Substring [Medium]

    思路

    manacher模板

    要点

    1. 注意 snull || s.length()0
    2. manacher O(n)

    代码

    O(n^2) version

    class Solution {
        public String longestPalindrome(String s) {
            if (s==null || s.length()==0) return "";
            int start=0, end=0;
            for (int i=0; i<s.length(); i++){
                int len=Math.max(
                    check(i, i, s),
                    check(i, i+1, s)
                );
                
                if (end-start<len){
                    start=i-(len-1)/2;
                    end=i+len/2;
                }
            }
            
            return s.substring(start, end+1);
        }
        
        private int check(int i, int j, String s){
            while (i>=0 && j<s.length() && s.charAt(i)==s.charAt(j)){
                i--; j++;
            }return j-i-1;
        }
    }
    

    O(n) version

    class Solution {
        private char[] str;
        public String longestPalindrome(String s) {
            if (s==null || s.length()==0) return "";
            return manacher(s);
        }
        
        public String manacher(String s){
            str=new char[2*s.length()+5];
            str[0]='#';
            for (int i=0; i<s.length(); i++){
                str[(i<<1)+1]=s.charAt(i);
                str[(i<<1)+2]='#';
            }
            
            int n=2*s.length()+1;
            int mr=-1, mid=-1, maxRad=0, maxRadIdx=0;
            int[] rad=new int[str.length];
            for (int i=0; i<str.length; i++){
                if (mr>i) rad[i]=Math.min(rad[2*mid-i], mr-i);
                else rad[i]=1;
                
                while (i-rad[i]>=0 && i+rad[i]<n && str[i+rad[i]]==str[i-rad[i]]) rad[i]++;
                if (rad[i]+i>mr){
                    mr=rad[i]+i; mid=i;
                }
                if (maxRad<rad[i]){
                    maxRad=rad[i]; maxRadIdx=i;
                }
            }
            
            if (maxRadIdx%2==1)
                return s.substring(maxRadIdx/2-(maxRad/2-1), maxRadIdx/2+(maxRad/2-1)+1);
            else return s.substring((maxRadIdx/2-1)-(maxRad/2-1), maxRadIdx/2+(maxRad/2-1)+1);
        }
    }
    
    6. ZigZag Conversion [Medium]

    6. ZigZag Conversion [Medium]

    思路

    找规律模拟即可

    要点

    1. StringBuilder用法: append, toString

    代码

    class Solution {
        public String convert(String s, int numRows) {
            StringBuilder ans=new StringBuilder("");
            int len=s.length();
            if (numRows==1) return s;
            
            for (int x=0; x<len; x+=2*numRows-2)
                ans.append(s.charAt(x));
            for (int y=1; y<numRows-1; y++)
                for (int x=0; x+y<len; x+=2*numRows-2){
                    ans.append(s.charAt(x+y));
                    if (x+y +2*numRows-2-2*y<len)
                        ans.append(s.charAt(x+y +2*numRows-2-2*y));
                }
            for (int x=numRows-1; x<len; x+=2*numRows-2)
                ans.append(s.charAt(x));
            
            return ans.toString();
        }
    }
    
    7. Reverse Integer [Easy]

    7. Reverse Integer [Easy]

    思路

    水题

    要点

    代码

    class Solution {
        public int reverse(int x) {
            if (x<0) return -1*solve(-1*x);
            return solve(x);
        }
        
        private int solve(int x){
            long res=0;
            while (x!=0){
                res=res*10+x%10;
                x/=10;
            }
            if (res<-(long)1<<31 || res>=(long)1<<31) return 0;
            return (int)res;
        }
    }
    
    
    8.String to Integer (atoi)[Medium]

    % 8.String to Integer (atoi)[Medium]

    思路

    垃圾模拟题

    要点

    考虑正则匹配

    代码

    class Solution {
        public int myAtoi(String str) {
            int sign=1, i=0, ans=0;
            str = str.trim();
            if (str.isEmpty()) return 0;
            else if (str.charAt(i)=='+') i++;
            else if (str.charAt(i)=='-') {i++; sign=-1;}
    
            while (i<str.length() && Character.isDigit(str.charAt(i))) {
                int ch=str.charAt(i)-'0';
                if (ans>(Integer.MAX_VALUE-ch)/10)
                    return sign>0?Integer.MAX_VALUE:Integer.MIN_VALUE;
                ans=ans*10+ch;
                i++;
            }
            return sign*ans;
        }
    }
    
    9. Palindrome Number [Easy]

    9. Palindrome Number [Easy]

    思路

    水题

    要点

    1. 反转字符串需要StringBuilder.reverse()

    代码

    class Solution {
        public boolean isPalindrome(int x) {
            StringBuilder ori=new StringBuilder(String.valueOf(x));
            ori.reverse();
            return ori.toString().equals(String.valueOf(x));
        }
    }
    
    10. Regular Expression Matching [Hard]

    @ 10. Regular Expression Matching [Hard]

    思路

    有点类似正则匹配的图, 画一个类似nfa一样的自动机可以发现是个dp, 模板串的状态用j表示, 那么待匹配串状态用i

    要点

    1. 利用java对象默认值是null, 可以避免初始化
    2. 事实上java基本类型中的数值默认值都是0, char的默认值是'u0000'是空字符

    代码

    class Solution {
        enum Result{
            TRUE, FALSE
        }
        
        private Result[][] res;
        private String s, p;
        public boolean isMatch(String s, String p) {
            this.s=s; this.p=p;
            res=new Result[s.length()+1][p.length()+1];
            
            return dp(0, 0);
        }
        
        private boolean dp(int i, int j){
            if (j==p.length()) return i==s.length();
            if (res[i][j]!=null) return res[i][j]==Result.TRUE;
            
            boolean match=(
                i<s.length() &&
                (s.charAt(i)==p.charAt(j) || p.charAt(j)=='.')
            ), tmp;
            if (p.length()>j+1 && p.charAt(j+1)=='*')
                tmp=(dp(i, j+2) || (match && dp(i+1, j)));
            else
                tmp=(match && dp(i+1, j+1));
            
            res[i][j]=tmp?Result.TRUE:Result.FALSE;
            return tmp;
        }
    }
    
  • 相关阅读:
    javascript创建类的6种方式
    c#匿名类型
    flex中在basewidget中不能使用图表组件问题
    Xamarin 后台持续定位与提示
    Net 并行知识学习
    占位
    axis 入门【原】
    Oracle存储过程procedure in、out、in out 模式参数【不发布,纯转】
    poi读取写入excel【未完,待续】
    poi读取写入word【未完,待续】
  • 原文地址:https://www.cnblogs.com/tanglizi/p/11493520.html
Copyright © 2020-2023  润新知