leetcode(17~30)

 14. Longest Common Prefix

本题注意用反向判断

String s=new String();
        char c;
        for(int i=0;i<strs[0].length();i++){
            c=strs[0].charAt(i);
            for(int j=0;j<strs.length;j++){
                if(strs[j].length()<=i||strs[j].charAt(i)!=c)//反向判断
                    return s;
            }
            s+=Character.toString(c);
        }
        return strs[0];

17. Letter Combinations of a Phone Number

这道题网上都说用dfs,其实,没有用dfs,用的就是递归的想法。

class Solution {
    public List<String> letterCombinations(String digits) {
        String[] s={"","1","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
        LinkedList<String> l=new LinkedList<String>();
        if(digits.length()==0)
            return l;//注意要判断一下为空的情况
        String curr="";
        int index=0;
        dfs(digits,index,curr,s,l);
        return l;
        }
     public void dfs(String digits,int index,String curr,String[] s,LinkedList<String> l){
            if(index==digits.length()){
                l.add(curr);
                return ;
            }
                
            int n=Character.getNumericValue(digits.charAt(index));
            for(int i=0;i<s[n].length();i++){
                String temp =curr;
                curr+=s[n].charAt(i);
                dfs(digits,index+1,curr,s,l);
                curr=temp;
            }
    }
}

19. Remove Nth Node From End of List

这道题,可以只遍历一次,用两个相隔n的指针就可以了,我的代码遍历了两次,因为只用了一次指针

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode curr=head;
        if(curr.next==null&&n==1)
            return null;
        LinkedList<ListNode> l=new LinkedList<ListNode>();
        while(curr!=null){
            l.push(curr);
            curr=curr.next;
        }
        ListNode par=curr;
        for(int i=0;i<n;i++){
            curr=l.pop();
        }
        if(l.isEmpty()){
            head=curr.next;
            curr.next=null;
        }
        else{
            par=l.pop();
            par.next=curr.next;
            curr.next=null;
        }
            
        return head;
    }
}

20. Valid Parentheses

这道题,我不知道第一种方法哪里错了,我在自己电脑上运行时,结果正确,我猜测是不满足空间复杂度的要求

方法一

class Solution {
    public boolean isValid(String s) {
        if(s.length()==0)
            return false;
        int l=0,m=0,b=0;
        for(int i=0;i<s.length();i++){
            if(l<0||m<0||b<0)
                return false;
            char c=s.charAt(i);
            n:switch(c){
                case '(':
                        l++;
                        break n;
                case ')':
                        l--;
                        break n;
                case '[':
                        m++;
                        break n;
                case ']':
                        m--;
                        break n;
                case '{':
                        b++;
                        break n;
                case '}':
                        b--;
                        break n;
            }
        }
        return l==0&&m==0&&b==0;
    }
}

方法二

class Solution {
    public boolean isValid(String s) {
        if(s==null)
            return false;
        HashMap<Character,Character> h=new HashMap<Character,Character>();
        h.put('{','}');
        h.put('[',']');
        h.put('(',')');
        LinkedList<Character> l=new LinkedList<Character>();
        for(int i=0;i<s.length();i++){
            if(s.charAt(i)=='('||s.charAt(i)=='['||s.charAt(i)=='{')
                l.push(s.charAt(i));
            else if(!l.isEmpty()&&s.charAt(i)==h.get(l.pop()))
                continue;
            else 
                return false;
        }
        return l.isEmpty();
}

21. Merge Two Sorted Lists

一定要注意在对链表做操作时,注意cur.next=new ListNode(x),分清楚情况,不能直接对null的赋值,cur必须要先有才能赋值,一定注意!

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

22. Generate Parentheses

错误示范

class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> l=new ArrayList<String>();
        if(n==0)
            return l;
        String curr="";
        int open=0;
        int close=0;
        backTracking(l,curr,open,close,n);
        return l;
    }
    public void backTracking(List<String> l,String curr,int open,int close,int max){
            if(curr.length()==max*2){
                l.add(curr);  
                return;
            }
            if(open<max){
                curr+="(";//不应加上这个,应该在递归回溯的时候加上,因为如果不合适的话,它将回        
                            溯到上一层
                backTracking(l,curr,open+1,close,max);
            }
            if(close<open){
                curr+=")";
                backTracking(l,curr,open,close+1,max); 
            }
        }
}

正确代码

class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> l=new ArrayList<String>();
        if(n==0)
            return l;
        String curr="";
        int open=0;
        int close=0;
        backTracking(l,curr,open,close,n);
        return l;
    }
    public void backTracking(List<String> l,String curr,int open,int close,int max){
            if(curr.length()==max*2){
                l.add(curr);  
                return;
            }
            if(open<max){
                backTracking(l,curr+"(",open+1,close,max);
            }
            if(close<open){
                curr+=")";
                backTracking(l,curr+")",open,close+1,max); 
            }
        }
}

23. Merge k Sorted Lists

这道题主要利用的就是之前说过的归并排序,利用分治法和数组融合

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
        if(lists.length==0)  return null;
        return sort(lists,0,lists.length-1);
    }
    public ListNode merge(ListNode l1,ListNode l2){
        ListNode l=new ListNode(0);
        ListNode cur=l;
        while(l1!=null&&l2!=null){
            if(l1.val<l2.val){
                cur.next=new ListNode(l1.val);
                l1=l1.next;
            }
            else{
                cur.next=new ListNode(l2.val);
                l2=l2.next;
            }
            cur=cur.next;
        }
        while(l1!=null){
            cur.next=new ListNode(l1.val);
            l1=l1.next;
            cur=cur.next;
        }
        while(l2!=null){
            cur.next=new ListNode(l2.val);
            l2=l2.next;
            cur=cur.next;
        }
            
        return l.next;
    }
    public ListNode sort(ListNode[] lists,int start,int end){
        if(start==end)
            return lists[start];
        else{
            ListNode left=sort(lists,start,(start+end)/2);
            ListNode right=sort(lists,(start+end)/2+1,end);
            return merge(left,right);
        }
    }
}

 

25. Reverse Nodes in k-Group

上图代表一次k链表反转,root,node,head代表的是什么

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        ListNode root=new ListNode(-1);
        ListNode res=root;
        root.next=head;
        int i=0;
        ListNode temp=head;
        //计算整个链表节点数,存在i中
        while(temp!=null){
            temp=temp.next;
            i++;
        }
        while(i>=k){//为了使最后一个不足k个节点的链表部分不进行反转,使i每经过一次k链表的反转后减k
            for(int j=0;j<k-1;j++){
                //用head当k中的反转后的最后一个,node代表root下一个,head代表k中末尾节点,root代表k节点的前一个节点,只有node每次不同,root和head在一次k链表反转中是不变的
                ListNode node=root.next;
                root.next=head.next;
                head.next=root.next.next;
                root.next.next=node;
            }
            root=head;
            head=root.next;
            i-=k;
        }
        return res.next;
    }
}

 26. Remove Duplicates from Sorted Array

class Solution {
    public int removeDuplicates(int[] nums) {
        int i=0,j=0;
        int k=1;
        while(i<nums.length-1){
            n:while(j<nums.length){
                if(nums[i]==nums[j])
                    j++;
                else{
                    k++;
                    nums[i+1]=nums[j];
                    break n;
                }
            }
            i++;
        }
        return k;
    }
}

27. Remove Element

class Solution {
    public int removeElement(int[] nums, int val) {
        Arrays.sort(nums);
        int i=0,j=nums.length-1,k=0;
        if(nums.length==0)
            return 0;
        while(i<=j){                  //一定注意这块有等号
            if(nums[i]==val){
                if(nums[j]!=val){
                    nums[i++]=nums[j--];
                    k++;
                }
                else j--;
            }
            else{
                i++;
                k++;
            }
        }
        return k;
    }
}

29. Divide Two Integers

这道题注意:1)其实溢出就只有一种情况,在代码第一个if考虑就可以了,

                      2)long和int转换,一定要将dividend和divisor转换成long

                      3)注意两个while循环,采用的是二分法。

class Solution {
    public int divide(int dividend, int divisor) {
         if(dividend ==Integer.MIN_VALUE&& divisor == -1)
             return Integer.MAX_VALUE;
        if(dividend==0||divisor==0)
            return 0;
        boolean sign=true;
        if((dividend<0&&divisor>0)||(dividend>0&&divisor<0))
            sign=false;
        long a=Math.abs((long)dividend);
        long b=Math.abs((long)divisor);
        if(a<b)
            return 0;
        long result=0;
        long sum=0;
        long pow=0;
        while(a>=b){
            sum = b;
            pow = 1;
            while(sum+sum<=a){
                sum+=sum;
                pow+=pow;
            }
            a-=sum;
            result+=pow;
        }
        return sign==true?(int)result:(int)-result;
    }
}

30. Substring with Concatenation of All Words

这道题主要思想:就是利用两个HashMap存储每个单词,一个存储words里的单词及其出现的次数,另一存储在搜索字符串s中出现的单词及其次数,两个哈希表里所对应的单词(key)的value一样的话,就匹配成功。注意HashMap更新映射时的用到的方法,还有它只有containsKey和containsValue的用法,没有contains的用法。

class Solution {
    public List<Integer> findSubstring(String s, String[] words) {
        List<Integer> res=new ArrayList<Integer>();
        int wordsNum=words.length;
        if(wordsNum==0)
            return res;
        int wordLen=words[0].length();
        HashMap<String,Integer> h1=new HashMap<String,Integer>();
        for(int i=0;i<words.length;i++){
            h1.put(words[i],h1.getOrDefault(words[i],0)+1);
        }
        for(int i=0;i<=s.length()-wordLen*wordsNum;i++){
            int num=0;
            HashMap<String,Integer> h2=new HashMap<String,Integer>();
            n:while(num<wordsNum){
                String word=s.substring(i+num*wordLen,i+(num+1)*wordLen);
                if(h1.containsKey(word)){
                    h2.put(word,h2.getOrDefault(word,0)+1);
                    if(h2.get(word)>h1.get(word))
                        break n;
                }
                else
                    break n;
                num++;
            }
            if(num==wordsNum)//num和wordsNum不一定一样,一样才算匹配成功
                res.add(i);
        }
        return res;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值