[高频] 一.Interview Style

512.Decode Ways:点击打开链接

思路:总是从f[i]看前i-1位数字能够解析的结果

          有两种方式:前i-1位到前i位,只要第i-1位不是数字0,前i位的结果数就是前i-1位的结果数

                            前i-2位到前i位,只要第i-2位和第i-1位两位上的数字介于10和26之间,就会又增加一种结果数

注意:1. 新建数组的时候数组长度要多一位,s.length()+1

         2. f[0]和f[1]的初始化问题,使得如果第一位为0的字符串,返回的结果数是0

例如:01:f[0]=1, f[1]=0 -> 结果f[2]=f[1]=0

public class Solution {
    /**
     * @param s a string,  encoded message
     * @return an integer, the number of ways decoding
     */
    public int numDecodings(String s) {
        if(s==null || s.length()==0){
            return 0;
        }
        
        int[] f=new int[s.length()+1];
        f[0]=1;
        f[1]=s.charAt(0)!='0'?1:0;
        
        for(int i=2;i<=s.length();i++){
            if(s.charAt(i-1)!='0'){
                f[i]=f[i-1];
            }
            
            int twoDigits=(s.charAt(i-2)-'0')*10+s.charAt(i-1)-'0';
            if(twoDigits>=10 && twoDigits<=26){
                f[i]+=f[i-2];
            }
        }
        return f[s.length()];
    }   
}

638.Strings Homomorphism:点击打开链接

思路:两次映射,s->t一次,t->s一次

注意:不能只做一次映射,如果"app"->"dog"是可以的,但是"dog"->"app"就犯了两个字母映射到同一个字母的错误

public class Solution {
    /**
     * @param s a string
     * @param t a string
     * @return true if the characters in s can be replaced to get t or false
     */
    public boolean isIsomorphic(String s, String t) {
        if(s==null || t==null){
            return true;
        }
        Map<Character,Character> map=new HashMap<>();
        for(int i=0;i<s.length();i++){
            if(!map.containsKey(s.charAt(i))){
                map.put(s.charAt(i),t.charAt(i));
            }else{
                if(map.get(s.charAt(i))!=t.charAt(i)){
                    return false;
                }
            }
        }
        Map<Character,Character> mapSecond=new HashMap<>();
        for(int i=0;i<t.length();i++){
            if(!mapSecond.containsKey(t.charAt(i))){
                mapSecond.put(t.charAt(i),s.charAt(i));
            }else{
                if(mapSecond.get(t.charAt(i))!=s.charAt(i)){
                    return false;
                }
            }
        }
        return true;
    }
}
public class Solution {
    /**
     * @param s a string
     * @param t a string
     * @return true if the characters in s can be replaced to get t or false
     */
    public boolean isIsomorphic(String s, String t) {            //写法二:同样的思路
        if(s==null || t==null){ 
            return true;
        }
        HashMap<Character,Character> map = new HashMap<>();  
        HashSet<Character> repeat = new HashSet<>();  
        for(int i = 0;i<s.length();i++){                         //例如"dog"->"app"
            if(!map.containsKey(s.charAt(i))){                   //遍历到第三个字母,map不包含字母g,但是repeat已经有p
                if(repeat.contains(t.charAt(i))){                //repeat的p是遍历第二个字母的时候放进去的
                    return false;                                     
                }  
                map.put(s.charAt(i) , t.charAt(i));              //在双方都没有的情况下,map和repeat同步加入
                repeat.add(t.charAt(i));  
            }else{  
                if(map.get(s.charAt(i)) != t.charAt(i)){  
                    return false;  
                }  
            }  
        }  
        return true; 
    }
}

626.Rectangle Overlap:点击打开链接

思路:考虑不重合的情况,有四种相对位置


/**
 * Definition for a point.
 * class Point {
 *     public int x, y;
 *     public Point() { x = 0; y = 0; }
 *     public Point(int a, int b) { x = a; y = b; }
 * }
 */

public class Solution {
    /**
     * @param l1 top-left coordinate of first rectangle
     * @param r1 bottom-right coordinate of first rectangle
     * @param l2 top-left coordinate of second rectangle
     * @param r2 bottom-right coordinate of second rectangle
     * @return true if they are overlap or false
     */
    public boolean doOverlap(Point l1, Point r1, Point l2, Point r2) {
        if(l1.x>r2.x || r1.x<l2.x){
            return false;
        }
        if(l1.y<r2.y || r1.y >l2.y){
            return false;
        }
        
        return true;
    }
}
637.Check Word Abbreviation: 点击打开链接

思路:两个指针,分别指向两个字符串的起始位置,往后遍历,出现的情况只有数字和字母,做相应处理,直到最后

public class Solution {
    /**
     * @param word a non-empty string
     * @param abbr an abbreviation
     * @return true if string matches with the given abbr or false
     */
    public boolean validWordAbbreviation(String word, String abbr) {
        if(word==null || abbr==null){
            return false;
        }
        
        int i=0;int j=0;
        char[] w=word.toCharArray();                                   //方便后面用a[j]的形式,不用charAt麻烦
        char[] a=abbr.toCharArray();
        
        while(i<word.length() && j<abbr.length()){                     //出现的只有数字和字母两种情况
            if(a[j]>='0' && a[j]<='9'){                                //如果是数字,不能有前导零
                if(a[j]=='0'){                               
                    return false;
                }
                int val=0;
                while(j<abbr.length() && a[j]>='0' && a[j]<='9'){      //非前导零的情况拿出连着的数字的大小
                    val=val*10+a[j++]-'0';
                }
                i+=val;                                                //同时指向字符串word的指针移动相应的位数
            }else{                                                     //如果是字母,要看两边相对应的是否相同
                if(w[i++]!=a[j++]){
                    return false;
                }
            }
        }
        
        return i==word.length() && j==abbr.length();                   //直到判断到头,因为i++和j++正好是最后一个字符
    }                                                                  //所有i和j多一个,要到字符串的长度
}

639. Words Abbreviation:点击打开链接

思路:每一个单词装在HashMap里并计数,有重复就增加此单词的prefix[i]继续求,直到所有的都为unique

注意:最后HashMap里装的是分析过的所有情况的个数,而result数组里的才是结果

例如:"apple", “apble”

          最后map里{apple=1,a3e=2,apble=1,ap2e=2}

          最后result数组里{apple,apble}


public class Solution {
    /**
     * @param dict an array of n distinct non-empty strings
     * @return an array of minimal possible abbreviations for every word
     */
    public String[] wordsAbbreviation(String[] dict) {
        if(dict==null || dict.length==0){
            return new String[0];
        }
        
        int len = dict.length;
        String[] result = new String[len];
        int[] prefix = new int[len];
        Map<String, Integer> map = new HashMap<>();
        boolean unique = true;
        
        for(int i = 0; i < dict.length;i++){
            prefix[i] = 1;
            result[i] = getAbbre(dict[i], prefix[i]);
            if(!map.containsKey(result[i])){
                map.put(result[i], 1);
            }else{
                map.put(result[i], map.get(result[i]) + 1);
                unique = false;
            }
        }
        
        while(unique==false){
            unique=true;
            for(int i = 0; i < len; i ++){
                if(map.get(result[i]) > 1){
                    prefix[i]++;                                             //个数大于1里面的每一个的substring都要多一位
                    result[i] = getAbbre(dict[i], prefix[i]);
                    if(!map.containsKey(result[i])){
                        map.put(result[i], 1);
                    }else{
                         map.put(result[i], map.get(result[i]) + 1);
                         unique=false;
                    }
                }
            }
            if(unique==true){                                               //直到每一个unique=true                    
                break;
            }
        }
        return result;
    }
    
    private String getAbbre(String s,int prefix){
        if(s.length()-prefix<=2){
            return s;
        }
        return s.substring(0,prefix)+(s.length()-prefix-1)+s.charAt(s.length()-1);  //substring方法参数(起始位置,长度)
    }
}







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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值