漂亮的代碼JAVA版

leetcode949 

	class Solution {
	    public String largestTimeFromDigits(int[] A) {
	        int[] f = new int[10];
	        for(int x : A)f[x]++;
	        for(int h = 23;h >= 0;h--){
	        	for(int m = 59;m >= 0;m--){
	        		int[] g = new int[10];
	        		for(int i = h, j = 0;j < 2;i /= 10,j++)g[i%10]++;
	        		for(int i = m, j = 0;j < 2;i /= 10,j++)g[i%10]++;
	        		if(Arrays.equals(f, g))return String.format("%02d:%02d", h, m);//將h,m以兩位的形式按字符串輸出
	        	}
	        }
	        return "";
	    }
	}

leetcode332

HashMap<String, PriorityQueue<String>> map = new HashMap<String, PriorityQueue<String>>();
    LinkedList<String> result = new LinkedList<String>();

    public List<String> findItinerary(String[][] tickets) {
        for (String[] ticket : tickets) {
            if (!map.containsKey(ticket[0])) {
                PriorityQueue<String> q = new PriorityQueue<String>();
                map.put(ticket[0], q);
            }
            map.get(ticket[0]).offer(ticket[1]);
        }
        fun("JFK");
        return result;
    }

    public void fun(String s) {
        PriorityQueue<String> q = map.get(s);

        while (q != null && !q.isEmpty()) {
            fun(q.poll());
        }
        result.addFirst(s);
    }

使用優先級隊列,來保證每次取出的都是按英文字母排序最小的(同時對於有去無回的情況,必定是放在最後面,然後結果從最後加回來)

leetcode488

class Solution {
    public int dfs(String board,int[]a1){
        if(board.equals(""))return 0;
        int len=board.length();
        int res=Integer.MAX_VALUE;
        for(int i=0;i<len;){
            int j=i++;
            while (i<len&&board.charAt(i)==board.charAt(j))i++;
            int inc=3-i+j;
            int used=inc>0?inc:0;

            if(a1[board.charAt(j)-'A']-used>=0){
                a1[board.charAt(j)-'A']-=used;
                int temp=dfs(board.substring(0,j)+board.substring(i,len),a1);
                if(temp>=0)res=Math.min(temp+used,res);
                a1[board.charAt(j)-'A']+=used;
            }

        }
        return res==Integer.MAX_VALUE?-1:res;
    }
    public int findMinStep(String board, String hand) {
        int[]a1=new int[26];
        for(char c:hand.toCharArray()){
            a1[c-'A']++;
        }
        return dfs(board,a1);
    }

}

利用string的不可變性和遞歸,進行字符串消除。

利用兩個指針,自加,確定消除範圍

利用遞歸返回值+used值,得到最後的返回值,即,每一次返回的都是最小,然後實現最後總的最小(有點dp的味道)

 

leetcode753

首先,對於數學上n位數,總是能取後n-1位然後加一位新的,構成一個新的數;這樣做完以後,可以把k^n種情況全部遍歷一遍。(具體原因未知,反正這樣做就可以了)

這裏比較漂亮的地方在於,利用stringbuilder的可變性,最終構造出答案,同時利用if(dfs())成功,直接返回,這一特性,使得在找到答案之後直接返回。利用hashset去重(這裏所有的情況不是用boolean來判斷,而是用hashset來判斷)

class Solution {
    public boolean dfs(StringBuilder res,int total,int n,int k,HashSet<String>a,int count){
        if(count==total)return true;
        String temp=res.substring(res.length()-n+1);
        for(int i=0;i<k;i++){
            if(a.contains(temp+(char)(i+'0')))continue;
            res.append((char)(i+'0'));
            a.add(temp+(char)(i+'0'));
             
            if(dfs(res,total,n,k,a,count+1))return true;
            a.remove(temp+(char)(i+'0'));
            res.deleteCharAt(res.length()-1);
        }
        return false;
    }
    public String crackSafe(int n, int k) {
        StringBuilder res=new StringBuilder();
        for(int i=0;i<n;i++){
            res.append('0');
        }
        HashSet<String>a=new HashSet<>();
        a.add(res.toString());
        int count=1;
        dfs(res,(int)Math.pow(k,n),n,k,a,count);
        return res.toString();
    }
}

 leetcode966

1.數組變hashset Arrays.asList(wordlist)

2.hashmap putifAbsent,只將第一個非重複的元素記錄下來

 public String[] spellchecker(String[] wordlist, String[] queries) {
        Set<String> words = new HashSet<>(Arrays.asList(wordlist));
        HashMap<String, String> cap = new HashMap<>();
        HashMap<String, String> vowel = new HashMap<>();
        for (String w : wordlist) {
            String lower = w.toLowerCase(), devowel = lower.replaceAll("[aeiou]", "#");
            cap.putIfAbsent(lower, w);
            vowel.putIfAbsent(devowel, w);
        }
        for (int i = 0; i < queries.length; ++i) {
            if (words.contains(queries[i])) continue;
            String lower = queries[i].toLowerCase(), devowel = lower.replaceAll("[aeiou]", "#");
            if (cap.containsKey(lower)) {
                queries[i] = cap.get(lower);
            } else if (vowel.containsKey(devowel)) {
                queries[i] = vowel.get(devowel);
            } else {
                queries[i] = "";
            }
        }
        return queries;
    }

leetcode 691

首先,dp公式在於,dp[strnew]=min(dp[strnew-sticker]+1);

那麼難點在於,如何利用字符串,作爲dp的索引,所以這裏用到了hashmap

但是對於不同的字符串,字母的排列方式也不一樣,但各類字符的總數可能一樣!因此,這裏又出現了一個新的難點,如何解決字符總數一樣但排列方式不一樣!因此,這裏採用的是將string變爲charArray之後,再重新排列,aaabbb這樣

那麼如何解決在一個字符串中減去另一個字符串呢?方法是,首先記錄總的,然後再對於每個字符串,數組記錄個數,total-every,最後構建一個新的字符串。

還有一個難點,如何判斷一個字符串中是否含有目標字符串中的任意一個字符呢?這裏採用的方法是從開頭開始判斷,每次解決開頭的字符(因爲最終要解決所有的)。

class Solution {
    public int minStickers(String[] stickers, String target) {
        int len=stickers.length;
        int[][]mp=new int[len][26];
        for(int i=0;i<len;i++){
            for(char c : stickers[i].toCharArray())mp[i][c-'a']++;
        }
        Map<String,Integer>dp=new HashMap<>();
        dp.put("",0);
        return help(mp,dp,target,len);
    }
    int help(int[][]mp,Map<String,Integer>dp,String target,int len){
        if(dp.containsKey(target))return dp.get(target);
        int[]tar=new int[26];
        for(char c:target.toCharArray())tar[c-'a']++;
        int res=Integer.MAX_VALUE;
        for(int i=0;i<len;i++){
            if(mp[i][target.charAt(0)-'a']==0)continue;
            StringBuilder t=new StringBuilder();
            for(int j=0;j<26;j++){
                int l=Math.max(tar[j]-mp[i][j],0);
                for(int k=0;k<l;k++)t.append((char)('a'+j));
            }
            int b=help(mp,dp,t.toString(),len);
            if(b<0)return -1;
            res=Math.min(res,b+1);
        }
        dp.put(target,res);
        return res==Integer.MAX_VALUE?-1:res;
    }
}

leetcode 43字符串相乘(同時也是拼多多筆試題,大整數相乘)

思路:第1個字符串的第i位乘以第2個字符串的第j位,結果可以儲存在數組的第i+j位,最後,只需要將數組中的所有元素取出,然後相加即可。

幾點需要注意:

1.首位爲0的字符應當刪除

2.取出之後當前位取模,其他位根據除法結果可能增加

3.刪除的時候至少要保留1位,即"0"*"0"="0",這時候的0不應該刪除

public String multiply(String num1, String num2) {
        int[]num=new int[num1.length()+num2.length()+2];
        char[]a1=num1.toCharArray(),a2=num2.toCharArray();
        int len1=a1.length-1,len2=a2.length-1;
        for(int i=len1;i>=0;i--){
            int b=a1[i]-'0';
            for(int j=len2;j>=0;j--){
                num[len1-i+len2-j]+=(a2[j]-'0')*b;
            }
        }
        StringBuilder res=new StringBuilder();
        for(int i=0;i<num.length;i++){
            int v=num[i];
            num[i]=v%10;
            v/=10;
            int cur=i+1;
            while (cur<num.length&&v>0){
                num[cur++]+=v%10;
                v/=10;
            }
            res.insert(0,(char)(num[i]+'0'));
        }
        while (res.length()>1&&res.charAt(0)=='0'){
            res.deleteCharAt(0);
        }
        return res.toString();
    }

 

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