【作业4】下标法:剑指 Offer 03. 数组中重复的数字
对应课程链接:拿捏算法面试:巧用数组下标法
作业要求:
1、给出 剑指 Offer 03. 数组中重复的数字 运行通过的代码。
2、要求额外空间复杂度是 O(1),时间复杂度O(n)
提示:1、可以让元素的值和它的下标相等,也就是通过交换,把元素 a 放到arr[a] 这个位置;如果有重复的数的话,就会出现有两个元素 a 对应到同一个 arr[a] 上,也就是出现了重复。
答案:其实我之前讲过,不懂可以看我之前到讲解:本题视频讲解(B站)
PS:如果你不知道怎么打卡,可以看这里:打卡细则
共以下 33 个回答
class Solution {
public int findRepeatDocument(int[] documents) {
if(documents null || documents.length 0) return -1;
}
`//代码
class Solution {
public int findRepeatDocument(int[] documents) {
int temp = 0;
for (int i = 0; i < documents.length; i++) {
while (documents[i] != i) {
if(documents[documents[i]] documents[i]){
return documents[i];
}
temp = documents[documents[i]];
documents[documents[i]] = documents[i];
documents[i] = temp;
}
}
return 0;
}
}“java
打卡
“`java
class Solution {
public int findRepeatDocument(int[] documents) {
for (int i = 0; i
打卡
它考察的是程序员的沟通能力,先问面试官要时间/空间需求!!!
最优解:下标法
最优解:下标法
Time:O(n),因为每次交换的时候都会让一个元素回到正确的位置上,最多只会交换n次
Space:O(1)
下标法:通过不停交换元素,使得元素和它所对应的下标相等,即num[i] = i
nums[i] nums[nums[i]]
排序法:
调用JDK中的任一排序函数进行排序,然后遍历数组,让i和i+1进行比较,重复就返回
下标: 0 1 2 3 4
元素: 2 0 1 2 3
排序: 0 1 2 2 3
Time:O(nlogn),主要是排序函数需要nlogn
Space:O(1)
哈希表:
new一个Hash表,然后遍历元素,判断一下这个元素是否在Hash表中,如果不存在就把它放进来,如果存在的话,说明重复了,直接返回
Time:O(n),遍历数组使用 O(n) ,HashSet 添加与查找元素皆为 O(1)
Space:O(n),HashSet 占用 O(n)大小的额外空间。
class Solution {
public int findRepeatNumber(int[] nums) {
int[] s = new int[nums.length];
for(int i = 0;i < nums.length; i++){
s[nums[i]]++; //
}
}
打卡
经过一晚上,又来打卡了,这次明白了最优解的思路
题目中,数组元素的范围被限制在数组的下标中,可以利用这个条件,把元素值也考虑到数组下标中去
遍历数组,交换当前位置的元素,一直到索引值 = 元素值为止
交换元素时会发生的两种情况:
1. 得到当前位置的元素值,停止本位置的交换,进入下一个位置的交换。
2. 数组中没有当前位置的元素值,在交换过程中,两个元素被交换到某一个相同的位置,发现重复元素,返回该元素值。
代码
“` javai){
class Solution {
public int findRepeatNumber(int[] nums) {
int[] s=new int[nums.length];
for(int i=0;i
i++;
continue;
}
if (nums[nums[i]]nums[i]){//下标为(索引6对应的那个数)索引6对应的数
return nums[i];
}
int temp;
temp=nums[i];
nums[i]=nums[temp];
nums[temp]=temp;
}
return 0;
}
}空间复杂度O(1)
“`
“`java
public int findRepeatNumber(int[] nums) {
代码的两头都要用“
“`”包起来
c++版本
一
//简单的一个下标法,只需拿一个数组记录重复出现的值作为编号,输出新的数组那个编号因为此时编号对应新数组的值大于1说明出现了两次以上
class Solution {
public int findRepeatNumber(int[] nums) {
int arr[] = new int [nums.length + 1];
for(int i = 0;i<nums.length;i++){
arr[nums[i]]++;
}
for(int j = 0;j<arr.length;j++){
if(arr[j]>1){
return j;
}
}
return -1;
}
}
你这个空间复杂度是 On 吧?
哦对,是的,习惯性打上O(1),得注意,而且也不符合要求
额外空间复杂度 O(1) 时间复杂度O(n)
下面是代码
时间复杂度O(1)
go语言解法。
时间复杂度:O(n),空间复杂度O(1)
作业四打卡
时间复杂度:O(n),空间复杂度O(1)
双指针也可以
你空间复杂度不符合要求哦,你这个额外空间复杂度是 O(n)了,要按照我要求,用下标法
兄弟,你这个可能过不了
//
你应该要去看一下题解视频,时间复杂度是可以做到O(1),你这种方法没有真正用到下标法哦
好的好的
老师,我写的和这个差不多,这个不是使用下标法进行了统计吗,是因为时间复杂度是O(n)不是最优解是吗?