Given an arbitrary ransom note string and another string containing letters from all the magazines, write a function that will return true if the ransom note can be constructed from the magazines ; otherwise, it will return false. 數組
Each letter in the magazine string can only be used once in your ransom note.code
Note: You may assume that both strings contain only lowercase letters.排序
canConstruct("a", "b") -> false canConstruct("aa", "ab") -> false canConstruct("aa", "aab") -> true
題目叫作Ransom Note,勒索信,剛開始我還沒理解這個題目的意思,尤爲這個標題,和magazine有啥關係呢?後來仔細想一想,才慢慢理解。勒索信,爲了避免暴露字跡,就從雜誌上搜索各個須要的字母,組成單詞來表達的意思。這樣來講,題目也就清晰了,判斷雜誌上的字是否可以組成勒索信須要的那些字符。 這裏須要注意的就是雜誌上的字符只能被使用一次,不過不用考慮大小寫的問題。 有一種最簡單的理解就是對於ransomNote裏每一個字符出現的次數必須小於或者等於該字符在magazine出現的次數。索引
解法一:這種解法比較簡單,就是將ransomNote的字符串挨個遍歷,每一個字符再從magazine裏遍歷匹配,只是再建立了個byte數組,數組每一個元素的索引表示magazine字符串的位置,元素值表示是否被校驗過,0表示還未被校驗過,非0就表示該位置已經被校驗過。不過這種作法效率不高。字符串
public boolean canConstruct(String ransomNote, String magazine) { boolean ret = true; byte[] bytes = new byte[magazine.length()]; for (int i = 0; i < ransomNote.length(); i++) { char c = ransomNote.charAt(i); boolean found = false; for (int j = 0; j < magazine.length(); j++) { if (bytes[j] == 0 && magazine.charAt(j) == c) { bytes[j]++; found = true; break; } } if (!found) { ret = false; break; } } return ret; }
解法二:將ransomNote和magazine都從小到大排序,而後對ransomNote遍歷,同時在magazine中匹配,若是匹配到了,則記住此時magazine中字符的索引,便於下次操做,由於都是排序的。若是直到magazine中字符已經大於ransomNote中字符了,就說明就再也匹配不到了,則表示匹配失敗。string
public boolean canConstruct(String ransomNote, String magazine) { boolean ret = true; char[] ra = ransomNote.toCharArray(); Arrays.sort(ra); char[] ma = magazine.toCharArray(); Arrays.sort(ma); int index = 0; boolean found = true; for (int i = 0; i < ra.length && ret; i++) { char ri = ra[i]; found = false; for (int j = index; j < ma.length; j++) { if (ma[j] > ri) { ret = false; break; } else if (ma[j] == ri) { index++; found = true; break; } else { index++; } } if (!found) { ret = false; break; } } return ret; }
解法三:這是LeetCode Discuss中的最熱代碼,它的原理就是列出了magazine的字母表,而後算出了出現個數,而後遍歷ransomNote,保證有足夠的字母可用,代碼很是清晰。it
public boolean canConstruct(String ransomNote, String magazine) { int[] arr = new int[26]; for (int i = 0; i < magazine.length(); i++) { arr[magazine.charAt(i) - 'a']++; } for (int i = 0; i < ransomNote.length(); i++) { if(--arr[ransomNote.charAt(i)-'a'] < 0) { return false; } } return true; }