【问题标题】:Ransom Note-Leetcode赎金笔记-Leetcode
【发布时间】:2021-07-15 19:20:54
【问题描述】:

我正在尝试383. Ransom Note LeetCode 挑战:

给定两个字符串ransomNotemagazine,如果ransomNote 可以从magazine 构造,则返回true,否则返回false。

magazine 中的每个字母在ransomNote 中只能使用一次。

示例1:

Input: ransomNote = "a", magazine = "b"
Output: false

示例2:

Input: ransomNote = "aa", magazine = "ab"
Output: false

示例3:

Input: ransomNote = "aa", magazine = "aab"
Output: true

这是我对上述 LeetCode 问题的解决方案:

class Solution {

    public boolean canConstruct(String ransomNote, String magazine) {

        if (ransomNote==null || ransomNote.length() == 0) return true;
        if (magazine==null || magazine.length() == 0) return false;
        boolean flag=false;
        boolean visited[]=new boolean[magazine.length()];
        Arrays.fill(visited,Boolean.FALSE);
        for(int i=0;i<ransomNote.length();i++){
            flag=false;
            for(int j=0;j<magazine.length();j++){
                if(ransomNote.charAt(i)==magazine.charAt(j) && !visited[j] ){
                    visited[j]=true;
                    flag=true;
                    break;
                }
            }
        }
        return flag;
    }
}

我能够通过 126 个案例中的 110 个,但代码中存在一些小错误。即使在我的试运行中我也找不到错误。

未通过的测试用例:

Input:
"fihjjjjei"
"hjibagacbhadfaefdjaeaebgi"

Output: true
Expected: false

【问题讨论】:

  • 这是 java 不是 c。
  • 我很惊讶您的代码通过了与您所说的一样多的案例。该代码本质上只是检查赎金票据的最后一个字母。那是因为您将每个字母的flag 设置为false,然后在找到未访问的匹配项时将其设置为true。所以最终的flag 值只取决于最后一个字母的结果。
  • 那我该怎么办???
  • 再想想你的逻辑?
  • 您可以修补已有的代码,或者从头开始使用全新的设计。我推荐后者。提示:counting sets 用于杂志和赎金票据。

标签: java algorithm for-loop data-structures


【解决方案1】:

如果在内循环结束时,flag 仍然是 false,则应退出外循环 for,因为这意味着您没有找到该字符的匹配项。

发生这种情况时继续匹配其他字符是没有用的,更糟糕​​的是,继续可能会使flag true 在外循环的最后一次迭代中再次出现,这会给出错误的结果。

所以添加为外循环体的最后一行:

if (!flag) return false;

请注意,此算法在非常大的字符串上效率不高,因为它的时间复杂度为 O(??),其中? 和? 是两个字符串的长度。如果您使用具有第二个字符串中每个字母的频率计数的映射,则可以在 O(?+?) 中完成。

【讨论】:

    【解决方案2】:
    public static 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++) {
            int offs = ransomNote.charAt(i) - 'a';
    
            if (arr[offs] > 0)
                arr[offs]--;
            else
                return false;
        }
    
        return true;
    }
    

    【讨论】:

    • 哇!很好的解决方案...我尝试了两张地图和一组
    【解决方案3】:

    O(m+n) 解,空间复杂度为 O(max(m,n))

    class Solution {
    public:
        bool canConstruct(string ransomNote, string magazine) {
            unordered_map<char, int> m1;
            unordered_map<char, int> m2;
            unordered_set<char> s;
            for(char& c : ransomNote) {
                m1[c]++;
                s.insert(c);
            }
            for(char& c : magazine) {
                m2[c]++;
            }
            for(char c : s) {
                if (m2.find(c) == m2.end() || m2.find(c)->second < m1.find(c)->second) {
                    return false;
                }
            }
            return true;
        }
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-14
      • 1970-01-01
      • 2020-11-19
      • 2019-02-21
      • 1970-01-01
      • 1970-01-01
      • 2019-03-25
      相关资源
      最近更新 更多