【LeetCode】383 Ransom Note(java)

原題

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;
    }
相關文章
相關標籤/搜索