Поиск значения с помощью цикла for и - PullRequest
0 голосов
/ 27 июня 2018

Вопрос такой:

Учитывая непустой массив целых чисел, каждый элемент появляется дважды, кроме одного. Найдите этот единственный.

Ввод: [4,1,2,1,2]
Выход: 4

мой код:

public static int singleNumber(int[] nums) {
     int answer = 0;
        for (int i =0; i<nums.length-1; i++) {
            for(int j = i+1; j<nums.length; j++) {
                if(nums[i] != nums[j]) {
                 answer = nums[i];      //this should be where I am wrong.
                }
            }
        }
        return answer;
    }

Я знаю, что на выходе было 4, а затем теперь оно будет изменено на 1. Я пытаюсь выяснить, как не изменить найденное значение после его обнаружения.

Ответы [ 6 ]

0 голосов
/ 28 июня 2018

Вот решение, которое использует ArrayList.indexOf и ArrayList.lastIndexOf. Если они одинаковы, у вас есть ответ.

public static int singleNumber(int[] nums) {
    int answer = 0;
    //ArrayList<Integer> list = new ArrayList<Integer>(Arrays.asList(nums));
    ArrayList al = new ArrayList();
    for (int i =0; i < nums.length; i++) {
        al.add(nums[i]);
    }

    for (int i =0; i < nums.length; i++) {
        int test = nums[i];
        if(al.indexOf(test) == al.lastIndexOf(test)){
            answer = nums[i];
        }
    }
    return answer;
 }
0 голосов
/ 28 июня 2018

Для этой проблемы я бы поразрядно XOR чисел. Равные числа взаимно отменят друг друга, и окончательным значением будет только одно целое число.

public static int singleNumber(int[] nums) {
     int answer = 0;
        for (int i =0; i<nums.length; i++) {
           answer = answer ^ nums[i];
        }
        return answer;
 }
0 голосов
/ 28 июня 2018

Вот еще одно решение, использующее Collectors.groupingBy из Java 8:

public static int singleNumber(int[] nums) {
    return Arrays.stream(nums).boxed()
            .collect(Collectors.groupingBy(a -> a, Collectors.counting()))
            .entrySet().stream().filter(e -> e.getValue() == 1).findFirst().get().getKey();
}

Идея такова:

  • группировка по номеру вхождения
  • затем найдите тот, который повторяется только один раз

Примечание. Я предполагаю, что ваш массив содержит хотя бы один элемент, иначе вы можете проверить длину перед поиском, а затем выдать исключение, например:

public static int singleNumber(int[] nums) throws IllegalArgumentException{
    if(nums.length == 0){
        throw new IllegalArgumentException("empty array");
    }
    return Arrays.stream(nums).boxed()
            .collect(Collectors.groupingBy(a -> a, Collectors.counting()))
            .entrySet().stream().filter(e -> e.getValue() == 1).findFirst().get().getKey();
}

Еще глубже, если вы хотите избежать ситуации, когда несколько раз повторяются только один раз, вы можете использовать:

public static int singleNumber(int[] nums) throws IllegalArgumentException {
    if (nums.length == 0) {
        throw new IllegalArgumentException("empty array");
    }
    Map<Integer, Long> grouping = Arrays.stream(nums).boxed()
            .collect(Collectors.groupingBy(a -> a, Collectors.counting()));
    if (grouping.values().stream().filter(c -> c == 1).count() > 1) {
        throw new IllegalArgumentException("more than one element is repeated one time");
    }

    return grouping.entrySet().stream()
            .filter(e -> e.getValue() == 1).findFirst().get().getKey();
}
0 голосов
/ 27 июня 2018

приведенные ниже изменения в вашем методе дадут вам ожидаемый ответ

public static int singleNumber(int[] nums) {

    int temp = 0;
    int answer = 0;

    for (int i = 0; i < nums.length; i++) {
        boolean flag = true;
        temp = nums[i];
        for (int j = 0; j < nums.length; j++) {
            if (temp == nums[j]) {
                if (i != j) {// if a match found then the loop will terminate
                    flag = false;
                    break;
                }
            }

        }
        if (flag == true) {
            answer = temp;
        }
    }
    return answer;
}
0 голосов
/ 27 июня 2018

Логика неверна - ваш внутренний цикл находит каждое число, которое не является единственным числом в массиве.

Я бы сохранил Set, чтобы отследить числа, с которыми я столкнулся. Когда вы впервые сталкиваетесь с номером, вы добавляете его в Set. Во второй раз, когда вы сталкиваетесь с этим, вы удаляете его из Set. Как только вы закончите работу с массивом, у вас будет Set с одним элементом, и ваш ответ:

public static int singleNumber(int[] nums) {
    Set<Integer> unique = new HashSet<>();
    for (int num : nums) {
        // add returns true if num is indeed new to unique
        if (!unique.add(num)) {
            unique.remove(num);
        }
    }

    return unique.iterator().next();
}
0 голосов
/ 27 июня 2018

Попробуйте это:

    int[] nums = new int[] {4,2,1,2,1};
         int answer = 0;
            for (int i =0; i<nums.length-1; i++) {
                int times = 0;
                int target = nums[i];
                for(int j : nums) {
                    if(j == target) {
                        times++;
                        if(times == 2) {
                            break;
                        }
                    }
                }
                if(times == 1) {
                    answer = target;
                    break;
                }
            }
            System.out.println(answer);

Вы должны войти в каждое число и посчитать, сколько meny в массиве, если есть только 1, вы мгновенно останавливаете конец цикла, устанавливая ответ

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...