陣列初體驗之陣列中重複的數字
技術標籤:資料結構與演算法
陣列初體驗之陣列中重複的數字
陣列 : 有限個 相同型別的變數 組成的有序集合
int[] arr;
int arr[];
// 靜態初始化
String[] strArr = {“和平精英”,“王者榮耀”,“開心消消樂”,“歡樂鬥地主”};
// 動態初始化
String[] strArr1 = new String[4];
陣列中重複的數字
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
解法
- 集合的解法 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; }
- 先排序後查詢
排序後重復元素相鄰
[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; }
- 臨時陣列
因為長度為 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;
}
- 交換位置查詢
[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;
}