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