标签:++ one length tab 调整数组顺序 数列 旋转数组的最小数字 dfs 后序遍历序列
重磅干货,第一时间送达数组中重复的数字
在一个长度为n的数组里的所有数字都在0到n-1的范围内。数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。
题目要求中可以发现,需要找出数组中重复的数字,长度为n的数组中必定存在元素是重复的!那么肯定是需要记录数组元素出现的次数,一遇到2立马跳出即可。所以我们需要额外的内存来记录,这个时候你想到使用什么样的数据结构?
我们抛开这道题,假设现在题目没有告诉你数组中是否存在元素重复,那假设现在利用刚刚题目的思路下来,当n较大的时候可能复杂度较高了。
我的想法就是将数组和集合结合下,先看看有没有重复。不知道小伙伴们有没有其他更好的思路?
用哈希表(字典)将出线的次数进行存储
PS:其实可以不用扩展内存来解这道题的。
# -*- coding:utf-8 -*-
class Solution:
# 这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
# 函数返回True/False
def duplicate(self, numbers, duplication):
# write code here
if numbers==None or len(numbers)<=1:
return False
usedDic=set() #集合
for i in range(len(numbers)):
if numbers[i]<0 or numbers[i]>len(numbers)-1:
return False
if numbers[i] not in usedDic:
usedDic.add(numbers[i])
else:
duplication[0]=numbers[i]
return True
return False
bool duplicate(int numbers[], int length, int* duplication) {
int flag = 0;
sort(numbers,numbers+length);
for(int i = 0; i<length-1; i++){
if(numbers[i] == numbers[i+1]){
* duplication = numbers[i];
flag = 1;
}
}
if(flag == 0) {* duplication = -1; return false;}
if(flag == 1) return true;
}
public boolean duplicate(int numbers[],int length,int [] duplication) {
if (length < 2 || numbers == null) {
return false;
}
// 是否有重复值
boolean isSuccess = false;
HashMap<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < length; i++) {
if (!map.containsKey(numbers[i])) {
map.put(numbers[i], 1);
} else {
int b = map.get(numbers[i]);
map.put(numbers[i], b+1);
isSuccess = true;
}
}
for (int i = 0; i < length; i++) {
if (map.get(numbers[i]) > 1){
duplication[0] = numbers[i];
return isSuccess;
}
}
return isSuccess;
}
做法2:假设现在不能使用额外的空间进行运算。
从头到尾扫描数组的每个数字,当扫描到下标为i的数字时,首先比较这个数字(假设为m)是否等于i,如果是,接着扫描下一个数字;如果不是,那么再将它和下标为m的数字对比,如果两者不相等,就把它和第m个数字交换,把m放到属于它的位置,如果两者相等,那么就找到了一个重复的数字。重复这个过程,知道发现一个重复的数字。
根据代码分析复杂度:所有操作都在输入数组上进行,不需要额外分配空间,因此空间复杂度为O(1);尽管代码中有一个两重循环,但是每个数字最多只要交换两次就能找到它自己的位置,因为总的时间复杂度为O(n)
# -*- coding:utf-8 -*-
class Solution:
# 这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
# 函数返回True/False
def duplicate(self, numbers, duplication):
# write code here
if numbers==None or len(numbers)<=1:
return False
for i in range(len(numbers)):
if numbers[i]<0 or numbers[i]>len(numbers)-1:
return False
for i in range(len(numbers)):
while (numbers[i]!=i):
if numbers[i]==numbers[numbers[i]]:
duplication[0]=numbers[i]
return True
else:
temp=numbers[i]
numbers[i]=numbers[temp]
numbers[temp]=temp
return False
注:面试季来了,不管是作为面试者还是以后作为面试官,了解算法这门程序员之间的沟通方式都是非常必要的。找过工作的朋友应该都听说过《剑指offer》,虽然书中只有六十多道题目,但是道道都是经典。
如果是单纯的面试需求,剑指offer的优先级肯定是在Leetcode之前,总的说它有三个优点:
它的缺点是:
剑指offer刷题交流群
扫码添加微信,一定要备注研究方向+地点+学校+昵称(如机器学习+上海+上交+汤姆)
▲长按加群
标签:++ one length tab 调整数组顺序 数列 旋转数组的最小数字 dfs 后序遍历序列
原文地址:https://blog.51cto.com/15054042/2564437