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; }