Возвращает true, если вы можете разделить список на меньший список с минимальными двумя значениями в разделенном списке, иначе возвращает false

#java #algorithm #debugging #stack #logic

#java #алгоритм #отладка #стек #Логические

Вопрос:

В колоде карт на каждой карте записано целое число.

Возвращает true тогда и только тогда, когда возможно разделить всю колоду на 1 или более групп карт, где:

В каждой группе не менее 2 карточек. Все карточки в каждой группе имеют одинаковое целое число.

Пример:

Ввод: deck = [1,2,3,4,4,3,2,1]

Вывод: true

Объяснение: Возможное разделение [1,1],[2,2],[3,3],[4,4] .

Я попытался решить эту проблему с помощью stack, но она работает не так, как ожидалось, и печатает false там, где предполагается печатать true. Я добавил комментарий для ясности моего кода.

пакет practicepkg;

 import java.util.Stack;

public class DeckInteger {

    public static void main(String[] args) {
        Stack<Integer> stack = new Stack<Integer>();
        //declaring individual variable for each integer and setting all of them to zero
        int p_1=0,p_2=0,p_3=0,p_4=0,p_5=0,p_6=0,p_7=0,p_8=0,p_9=0;
        
        //adding element which can form pair and should return true
        stack.add(1);
        stack.add(2);
        stack.add(1);
        stack.add(2);
        stack.add(1);
        stack.add(2);
        
        
        //checking till stack is empty and comparing the top of stack to all the individual integer and incrementing them and popping the top element 
        while(stack.empty()==false) {
            if(stack.peek()==1) {
                p_1 =1;
                stack.pop();                        
                break;
            } else if(stack.peek()==2) {
                p_2 =1;
                stack.pop();                        
                break;
            } else if(stack.peek()==3) {
                stack.pop();
                p_3 =1;
                break;
            } else if(stack.peek()==4) {
                stack.pop();
                p_4 =1;
                break;
            } else if(stack.peek()==5) {
                stack.pop();
                p_5 =1;
                break;
            } else if(stack.peek()==6) {
                stack.pop();
                p_6 =1;
                break;
            } else if(stack.peek()==7) {
                stack.pop();
                p_7 =1;
                break;
            } else if(stack.peek()==8) {
                stack.pop();
                p_8 =1;
                break;
            } else {
                stack.pop();
                p_9 =1;
                break;
            }
        }
        //checking if any of the integer variable have the value 1 then it cannot form pair as x>=2 so it should print false
        if(p_1==1||p_2==1||p_3==1||p_4==1||p_5==1||p_6==1||p_7==1||p_8==1||p_9==1) {
            System.out.println("False");
        }
        //print true as if any of the variable have a value other than one
        else {
            System.out.println("True");
        }
    }    
}
 

Ответ №1:

Если у вас есть a_i карты с целым i числом, то все возможные разделы будут делителями a_i , иначе эта карта не может быть разделена. Поэтому вам нужно только подсчитать все уникальные числа и вычислить их наибольший общий делитель. Этот наибольший общий делитель будет максимально возможным X.

Комментарии:

1. эй, вы можете сказать мне, почему мой код не работает?

2. Ваш код не работает, потому что у вас есть разрыв в вашем коде, он прерывает цикл while, и вы считаете только последнее число из вашего ввода, а не все из них. Предположим, что он остается после перехода от случая переключения. В любом случае, это неважно, потому что это все равно будет неверно после исправления. Например, если у вас есть числа [2, 2, 3, 3, 3] в качестве вашего ввода ваш код (после исправления) вернет true, в то время как для такого ввода нет раздела.

3. Если я удалю break , мы сможем создать раздел [2,2] и [3,3,3] кстати, мне нужно только проверить, имеет ли переменная значение, отличное от единицы.

4. ради всего Святого, большое вам спасибо. Это решило мою проблему. Ты лучший. 🙂

Ответ №2:

В коде, который вы используете break внутри каждого if условия. Таким образом, он выйдет из while цикла на самой первой итерации. Так что только p_1 будет равно 1 , а все остальные будут 0 . Существует гораздо лучший способ решить эту проблему, используя Maps with key в качестве целого числа и value в качестве его количества

Предполагая, что входные данные представлены в виде массива : int[] input

 private boolean isValidGroup(Stack<Integer> stack){
    Map<Integer, Integer> countMap = new HashMap<>();   
    while(!stack.empty()){
        countMap.merge(stack.pop(),1,Integer::sum);
    }
    // The above map would contain the count for each integer.
    // For input : {1,2,4,2,4,3,1,3} , the map would be {1:2,2:2,3:2,4:2}
    
    List<Integer> distinctCounts = countMap.values().stream().distinct().collect(Collectors.toList());
    // The above list contains the distinct group counts.

    // Ideally the number of distinct count value should be 1 and the value should be >=2.
    //In such case, we return true.
    return (distinctCounts.size()==1 amp;amp; distinctCounts.get(0)>=2);
}
 

Комментарии:

1. привет, спасибо за ваше решение. это выглядит намного элегантнее, хотя меня попросили решить это, используя только стек.

2. Даже в этом случае Map вместо 10 разных целочисленных переменных можно использовать. Также с map вы могли бы использовать одно if условие внутри while цикла

3. @BiggestNoob, я обновил ответ, используя Stack