题目导航
前言
刷题冲Java实习,每天坚持刷题!点击题目可以跳转到 leetcode
相应题目
1.找出数组中重复的数字
在一个长度为 n 的数组 nums
里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
限制 :2 <= n <= 100000
分析:
假设数组nums
为:[0,3,2,1,3,4]
而且题目限制数组中数据的大小在0到n-1,数组长度为n。
那么我们可将数组的下标映射成对应的元素是否为存在过。
思考一下:
- 例如,nums[1] = 3
- 将数值存储到
temp
,temp=nums[1] - 判断 nums[temp] 是否为负数,若是,则输出 temp
- 若不是则设置 nums[temp] 为其相反数,标识这个数值存在。nums[temp]*=-1;
- 循环1234步。
带入数组nums试试 nums
:[0,3,2,1,3,4]
- 因为 nums[1]=3
- 设置 nums[3]为相反数= -1
- 因为 nums[4]=3
- 判断 num[3]是否小于0(小于0则说明之前已将查询过对应原始元素3)
- 小于0,输出 nums[3]
动图理解
但是很快我们就发现,当第一位数字为0的时候,第4步是执行了跟没执行一样,找不到0的存在,所以我们现在开始寻找相同数字之前,将数组遍历,全体数据+1。使得所有数据都是正数,取相反数之后可以成为负数。在输出和比对的时候只需要将结果-1即可。
实现代码:
class Solution {
public int findRepeatNumber(int[] nums) {
for (int i = 0; i < nums.length ; i++){//因为0*-1还=0,所以变正数,范围(1,n)
nums[i]++;
}
for (int i = 0; i < nums.length ; i++) {
int temp = Math.abs(nums[i])-1;//nums[i]可能为负(为负是因为这个下标对应的元素出现过了),所以用绝对值表示
if (nums[temp]<0) return temp;//temp==Math.abs(nums[i])-1==原数字
nums[temp] *= -1 ;//将原数字对应的下标设置为复数
}
return 0;
}
}
补充一下
:怕大家不理解,我还是以数组nums
为:[0,3,2,1,3,4]为例子来 粗略 分析一下。
数组数据循环加1之后nums=[1,4,3,2,4,5]
- 因为 nums[1]=4,
对应原元素为4-1=3
- 设置 nums[3]为相反数= -2
- 因为 nums[4]=4,
对应原元素为4-1=3
- 判断 num[3]是否小于0(小于0则说明之前已将查询过对应原始元素3)
- 小于0,输出 nums[4]-1,
对应原元素数据为nums[4]-1=3
byebye,为了做动图顺手学了一下flash哈哈哈