1. 程式人生 > 其它 >陣列初體驗之陣列中重複的數字

陣列初體驗之陣列中重複的數字

技術標籤:資料結構與演算法

陣列初體驗之陣列中重複的數字

陣列 : 有限個 相同型別的變數 組成的有序集合

int[] arr;
int arr[];

// 靜態初始化
String[] strArr = {“和平精英”,“王者榮耀”,“開心消消樂”,“歡樂鬥地主”};
// 動態初始化
String[] strArr1 = new String[4];

image-20200915172303686
陣列中重複的數字

https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/

劍指 Offer 03. 陣列中重複的數字

找出陣列中重複的數字。

在一個長度為 n 的陣列 nums 裡的所有數字都在 0~n-1 的範圍內。陣列中某些數字是重複的,但不知道有幾個數字重複了,也不知道每個數字重複了幾次。請找出陣列中任意一個重複的數字。

示例 1:

輸入:
[2, 3, 1, 0, 2, 5, 3]
輸出:2 或 3

解法

  1. 集合的解法 set
    使用集合儲存已遍歷過的資料,新資料遍歷時,判斷是否在集合中存在,如果存在即為重複的
    public static int findRepeatNumber(int[] nums) {
        Set<Integer> set = new HashSet<>();
        // 遍歷陣列 iter快捷鍵
        for (int num : nums) {
            if (set.contains(num)) {
                System.out.println("發現重複元素" + num);
                return num;
            }
            System.out.println("新增元素" + num);
            set.add(num);
        }
        return -1;
    }
  1. 先排序後查詢
    排序後重復元素相鄰
    [2, 3, 1, 0, 2, 5, 3]
    [0, 1, 2, 2, 3, 3, 5]
    public static int findRepeatNumber1(int[] nums) {
        // 運算元組的工具類 進行排序
        System.out.println(Arrays.toString(nums));
        Arrays.sort(nums);
        System.out.println(Arrays.toString(nums));
        // itar快捷鍵  通過判斷相鄰元素是否相等  返回是否重複
        for (int i = 1; i < nums.length; i++) {
            if (nums[i] == nums[i - 1]) {
                return nums[i];
            }
        }

        return -1;
    }
  1. 臨時陣列
    因為長度為 n 的陣列 nums 裡的所有數字都在 0~n-1
    所以 臨時陣列中的索引 對應所有可能出現的數字
    遍歷時 將出現數字 對應到臨時陣列的索引位置 更改元素值 0 - 1
    當臨時陣列的元素 不為0時 說明此索引位置 已經出現過元素了

[2, 3, 1, 0, 2, 5, 3]

[0, 0, 0, 0, 0, 0, 0]
0 1 2 3 4 5 6

[0, 0, 1, 0, 0, 0, 0]
[0, 0, 1, 1, 0, 0, 0]
[0, 1, 1, 1, 0, 0, 0]
[1, 1, 1, 1, 0, 0, 0]

    public static int findRepeatNumber2(int[] nums) {
        System.out.println(Arrays.toString(nums));
        // 臨時陣列  所有元素預設是0
        int[] tmp = new int[nums.length];
        System.out.println(Arrays.toString(tmp));
        for (int i = 0; i < nums.length; i++) {
            int num = nums[i];
            // 如果已經複製 代表重複出現
            if (tmp[num] != 0) {
                return num;
            }
            // 找到臨時陣列的索引位置  賦值為1
            tmp[num] = 1;
            System.out.println(Arrays.toString(tmp));
        }
        return -1;
    }
  1. 交換位置查詢

[2, 3, 1, 0, 2, 5, 3]
0 1 2 3 4 5 6

[0, 1, 2, 3, 2, 5, 3]
0 1 2 3 4 5 6

[2, 3, 1, 0, 2, 5, 3]

遍歷陣列的過程中
希望當前位置 和 出現元素正好匹配上
先判斷 是否匹配 如果不匹配 進行交換 並且看需要交換的位置 是否存在期望元素
如果可以交換 交換之後 繼續遍歷當前位置 如果不可交換 即為重複元素
0 1 2 3 4 5 6
遍歷2 交換2和1 [1, 3, 2, 0, 2, 5, 3]
遍歷1 交換1和3 [3, 1, 2, 0, 2, 5, 3]
遍歷3 交換3和0 [0, 1, 2, 3, 2, 5, 3]
遍歷0 不交換
遍歷1 不交換
遍歷2 不交換
遍歷3 不交換
遍歷2 已經出現期望元素 是重複元素

public static int findRepeatNumber3(int[] nums) {
        System.out.println(Arrays.toString(nums));
        // [2, 3, 1, 0, 2, 5, 3]
        for (int i = 0; i < nums.length; i++) {

            // 如果索引正好等於元素本身  是期望的結果  跳過
            if (nums[i] == i) continue;

            // i = 0
            int num = nums[i]; // 2
            // 如果要交換的位置  已經有期望值  說明重複
            if (nums[num] == num) {
                System.out.println("當前索引為" + num + "的位置 已經有" + num + "值,重複了");
                return num;
            }
            int tmp = nums[num]; // 1
            nums[num] = num;
            nums[i] = tmp;
            // [1, 3, 2, 0, 2, 5, 3]
            // 交換仍需遍歷當前位置的值  所以抵消i++
            i--;
            System.out.println(Arrays.toString(nums));
        }

        return -1;
    }