bugfix> java > 投稿

質問はこれです:

整数の空でない配列を指定すると、1つを除くすべての要素が2回現れます。その1つを見つけます。

入力:[4,1,2,1,2,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に変更されます。 見つかった値を変更しないようにする方法を見つけようとしています。

回答 5 件
  • ロジックが間違っています-配列内の唯一の数値ではないすべての数値を内部ループが検出します。

    私は Set を維持します  出会った数字を追​​跡します。初めて数字に出会ったときは、それを Set に追加します 。 2回目に遭遇すると、それを 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();
    }
    
    

  • この問題では、数値のビットごとのXORを実行します。等しい数値は互いにキャンセルされ、1つの整数のみが最終値になります。

    public static int singleNumber(int[] nums) {
         int answer = 0;
            for (int i =0; i<nums.length; i++) {
               answer = answer ^ nums[i];
            }
            return answer;
     }
    
    

  • 以下のメソッドの変更により、期待される答えが得られます

    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;
    }
    
    

  • 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();
    }
    
    

    アイデアは次のとおりです。

    発生回数でグループ化

    その後、1回だけ繰り返されるものを見つけます


    注:配列に少なくとも1つの要素が含まれていると仮定します。そうでない場合は、検索する前に長さを確認してから、次のような例外をスローできます。

    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();
    }
    
    

  • 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;
     }
    
    

あなたの答え