3 數組中重複的數字
要求:
在一個長度爲 n 的數組裏的所有數字都在 0 到 n-1 的範圍內。數組中某些數字是重複的,但不知道有幾個數字是重複的,也不知道每個數字重複幾次。請找出數組中任意一個重複的數字。
時間複雜度 O(N),空間複雜度 O(1)。
Input:
{2, 3, 1, 0, 2, 5}
Output:
2
分析:難點 空間複雜度 O(1)。
那就不能用額外的的數組標記。
so:
用當前數組標記,值v挪到,input[v],這個值與當前的值交換位置。
當 input【v】爲2個或以上相同值時 return false. over
public boolean duplicate(int[] nums, int length, int[] duplication) {
if (nums == null || length <= 0)
return false;
for (int i = 0; i < length; i++) {
while (nums[i] != i) {
if (nums[i] == nums[nums[i]]) {//當num[i] 月 i 位置對應的數相等時,就證明這個數存在2個
duplication[0] = nums[i];
return true;
}
swap(nums, i, nums[i]);//交換位置,i 到i位置。
}
}
return false;
}
private void swap(int[] nums, int i, int j) {
int t = nums[i];
nums[i] = nums[j];
nums[j] = t;
}
4. 二維數組中的查找
題目描述
給定一個二維數組,其每一行從左到右遞增排序,從上到下也是遞增排序。給定一個數,判斷這個數是否在該二維數組中。
Consider the following matrix:
[
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]
Given target = 5, return true.
Given target = 20, return false.
解題思路
要求時間複雜度 O(M + N),空間複雜度 O(1)。其中 M 爲行數,N 爲 列數。
該二維數組中的一個數,小於它的數一定在其左邊,大於它的數一定在其下邊。因此,從右上角開始查找,就可以根據 target 和當前元素的大小關係來縮小查找區間,當前元素的查找區間爲左下角的所有元素。
參考
https://github.com/CyC2018/CS-Notes/blob/master/notes/劍指 Offer 題解 - 3~9.md