简体   繁体   English

找不到我的leetcode问题解决方案的问题

[英]Can't find the problem with my solution to leetcode problem

I am trying the ransom note challenge:我正在尝试赎金字条挑战:

Given two strings ransomNote and magazine, return true if ransomNote can be constructed by using the letters from magazine and false otherwise.给定两个字符串 ransomNote 和 magazine,如果可以使用 magazine 中的字母构造 ransomNote 则返回 true,否则返回 false。

Each letter in magazine can only be used once in ransomNote.杂志中的每个字母只能在 ransomNote 中使用一次。

Example 1:示例 1:

Input: ransomNote = "a", magazine = "b" Output: false Example 2:输入:ransomNote = "a", magazine = "b" Output: false 示例 2:

Input: ransomNote = "aa", magazine = "ab" Output: false Example 3:输入:ransomNote = "aa", magazine = "ab" Output: false 示例 3:

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

here is my solution:这是我的解决方案:

public static boolean canConstruct(String ransomNote, String magazine) {
        ArrayList<Character> ransomChar = new ArrayList<Character>();
        ArrayList<Character> magazineChar = new ArrayList<Character>();

        if (ransomNote.length() == 1 && magazine.length() == 1) {
            if (ransomNote.equals(magazine)) {
                return true;
            }
            return false;
        }

        else if (ransomNote.length() == 1 && magazine.length() > 1) {
            for (int i = 0; i < magazine.length(); i++) {
                if (magazine.charAt(i) == ransomNote.charAt(0)) {
                    return true;
                }
            }
            return false;
        }
        else if (ransomNote.length() > 1 && magazine.length() > 1) {
            for (int i = 0; i < ransomNote.length(); i++) {
                ransomChar.add(ransomNote.charAt(i));
            }
            for (int i = 0; i < magazine.length(); i++) {
                magazineChar.add(magazine.charAt(i));
            }
            while (ransomChar.size() > 1) {
                for (int i = 0; i < ransomChar.size(); i++) {
                    boolean flag = false;
                    for (int j = 0; j < magazineChar.size(); j++) {
                        if (ransomChar.get(i).equals(magazineChar.get(j))) {
                            ransomChar.remove(i);
                            magazineChar.remove(j);
                            flag = true;
                        }
                        else if (ransomChar.isEmpty()) {
                            return true;
                        }
                    }
                    if (!flag) {
                        return false;
                    }
                }
            }
            
            if (ransomChar.size() == 1 && magazineChar.size() == 1) {
                if (ransomChar.equals(magazineChar)) {
                    return true;
                }
                return false;
            }

            else if (ransomChar.size() == 1 && magazineChar.size() > 1) {
                for (int i = 0; i < magazineChar.size(); i++) {
                    if (ransomChar.get(0).equals(magazineChar.get(i))) {
                        return true;
                    }
                }
                return false;
            }
        }
        return false;
    }

I am passing most test cases but it throws an error at input:我通过了大多数测试用例,但它在输入时抛出错误:

    "bg"
    "efjbdfbdgfjhhaiigfhbaejahgfbbgbjagbddfgdiaigdadhcfcj"

It throws error:它抛出错误:

java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0
at line: if (ransomChar.get(i).equals(magazineChar.get(j)))

Here's a simple way to attack your problem by building a set of candidate characters from magazine .这是通过构建一组来自magazine的候选字符来解决您的问题的简单方法。 Once you've done that, you just iterate over the ransomNote , checking the set for each character.完成后,您只需遍历ransomNote ,检查每个字符的集合。 If you find it, you remove it from the set.如果找到它,则将其从集合中移除。 If you don't, then you return false .如果不这样做,则返回false If you make it all the way through, you return true .如果你一直坚持下去,你就会返回true You need to use a MultiSet because you need to be able to represent multiple copies of the same character in the magazine.您需要使用MultiSet ,因为您需要能够表示杂志中同一角色的多个副本。

Here's how to do that:以下是如何做到这一点:

public static boolean canConstruct(String ransomNote, String magazine) {
    MultiSet<Character> magazineChars = new HashMultiSet<>();
    for (int i = 0; i < magazine.length(); i++)
        magazineChars.add(magazine.charAt(i));
    for (int i = 0 ; i < ransomNote.length(); i++) {
        Character c = ransomNote.charAt(i);
        if (magazineChars.contains(c))
            magazineChars.remove(c);
        else
            return false;
    }
    return true;
}

On each iteration of this loop:在此循环的每次迭代中:

 for (int i = 0; i < ransomChar.size(); i++) { boolean flag = false; for (int j = 0; j < magazineChar.size(); j++) { if (ransomChar.get(i).equals(magazineChar.get(j))) { ransomChar.remove(i); magazineChar.remove(j); flag = true; } else if (ransomChar.isEmpty()) { return true; } } if (;flag) { return false; } }

, you know that i is initially less than ransomChar.size() , so that it is safe to perform ransomChar.get(i) . ,您知道i最初小于ransomChar.size() ,因此执行ransomChar.get(i)是安全的。

However, the inner loop may remove one (or more!) elements of ransomChar , after which it may no longer be true that i is less than ransomChar.size() .但是,内部循环可能会删除ransomChar的一个(或多个!)元素,之后i小于ransomChar.size()可能不再为真。 The inner loop continues to iterate, and as a result, it can attempt to retrieve an element of ransomChar that does not exist.内部循环继续迭代,因此,它可能会尝试检索不存在的ransomChar元素。

Honestly, the code overall is a mess.老实说,代码总体上是一团糟。 Other than this specific issue,除了这个具体问题,

  • I see no need why you need special cases for all the variations on sizes of note and magazine.我看不出为什么你需要特殊的盒子来容纳所有不同尺寸的便条和杂志。 I think you might write better code for this if you devoted some effort to designing an approach that just works correctly for all cases.我认为,如果您付出一些努力来设计一种适用于所有情况的方法,您可能会为此编写更好的代码。

  • you are not making good use of the available features of the classes you are using您没有充分利用您正在使用的类的可用功能

  • you are not making good use of general Java language features that would be applicable.您没有充分利用适用的一般 Java 语言功能。

For example, I might write that particular loop as:例如,我可能会将该特定循环写为:

                for (Character c : ransomChar) {
                    if (!magazineChar.remove(c)) {
                        return false;
                    }
                }
                return true;

And that's before we come to the fact that you've chosen a suboptimal algorithm.那是在我们得出您选择了次优算法的事实之前。 Its execution time will scale as note size * magazine size, whereas there are alternatives that will scale as note size + magazine size, instead.它的执行时间将按笔记大小 * 杂志大小缩放,而有替代方案将按笔记大小 + 杂志大小缩放。 That may in fact be important, because choice of an efficient algorithm is one thing that the test cases for coding challenges such as this often try to detect.这实际上可能很重要,因为选择一种有效的算法是编码挑战的测试用例经常尝试检测的一件事。

Please find small and simple solution with Time complexity O(n) and Space complexity O(256) or O(1)请找到时间复杂度 O(n) 和空间复杂度 O(256) 或 O(1) 的小而简单的解决方案

 int[] count = new int[256];
        for (char c : magazine.toCharArray()) {
            count[c]++;
        }
        for (char c : ransomNote.toCharArray()) {
            if (count[c]-- == 0) return false;
        }
        return true;  

Result结果

在此处输入图像描述

@Harsh so you are trying to access the element of ransomChar which do not even exists. @Harsh 所以你试图访问甚至不存在的 ransomChar 元素。 look at the lines看线条

if (ransomChar.get(i).equals(magazineChar.get(j))) {
    ransomChar.remove(i);
    magazineChar.remove(j);
    flag = true;
}

you are removing the elements from the lists and and every time you remove the elements from the list their indexing changes and and when it rechecks the condition the list is already empty after several iteration.您正在从列表中删除元素,并且每次从列表中删除元素时,它们的索引都会发生变化,并且当它重新检查条件时,经过几次迭代后列表已经为空。 Hence giving the run time error.因此给出运行时错误。 to avoid this you should check whether the list is empty or not, first (you are checking it after).为避免这种情况,您应该首先检查列表是否为空(之后再检查)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 .onBindViewHolder 的问题(找不到我的代码的解决方案) - Problem with the .onBindViewHolder (Can't find a solution for my code) leetcode 上的字符串 a 到 i 问题我的解决方案在出现 2 个连续符号的情况下失败 - string a to i problem on leetcode my solution fails incase of 2 consecutive signs 对于这个 Leetcode 问题(单词搜索),为什么我的第一个解决方案比我的第二个解决方案运行得慢? - Why does my first solution run slower than my second solution for this Leetcode problem (Word Search)? 这个 leetcode 问题的记忆。 我如何记住这个递归解决方案 - Memoization of this leetcode problem. How do I memoize this recursive solution 二和 LeetCode 问题:蛮力解决方法不起作用? - Two Sum LeetCode Problem: Brute force solution approach not working? 似乎找不到我的空指针问题 - Can't seem to find my null pointer problem 找不到错误我对makeBricks问题java的解决方案 - can't find error my sollution to makeBricks problem java 我在“Codeforces”问题中找不到我的错误 - I can't find my mistake in a "Codeforces" problem LeetCode 问题中的约束是什么? - What are the constraints in LeetCode Problem? 谁能帮我弄清楚为什么这个while循环对“回文数”LeetCode问题不起作用? - Can anyone help me figure out why this while loop won't work for the “Palindrome Number” LeetCode problem?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM