来源:力扣(LeetCode)
找出数组中重复的数字
题目描述
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
限制:2 <= n <= 100000
我的题解
int findRepeatNumber(int* nums, int numsSize){
for(int i=0;i<numsSize;i++)
{
for(int j=i+1;j<numsSize;j++)
{
if(nums[i]==nums[j])
{
return nums[i];
}
}
}
return -1;
}
结果:超时,原因会在下面详细描述。
网上题解
方案一:暴力求解(同我的题解)
思路:遍历数组中的每个元素,然后遍历剩下的元素,看是否存在相同的元素。
代码如下:
public int findRepeatNumber(int[] nums)
{
for(int i=0;i<nums.length;i++)
{
for(int j=i+1;j<nums.length;j++)
{
if(nums[i]==nums[j])
{
return nums[i];
}
}
}
return -1;
}
结果:通过。
原因:根据复杂度可以看出,此种解法的时间复杂度为O(n^2),随着问题规模的变大,花费时间将会越来越长。
个人想法:时间换空间,空间复杂度为O(1)。
疑问:我使用的C语言进行编写,但是结果为超时,如果使用Java进行编写,同样为暴力解法,结果确实通过。不理解。。。
由于数据规模限制为2 <= n <= 100000
,所以总体来说暴力解决的代码性能是非常差的。
方案二:哈希查找
哈希表跟暴力解法的思路是相同的,但是区别在于哈希表判断是否存在的时间复杂度为O(1)。
算法步骤为:
- 先初始化一个哈希表(HashSet)
- 然后遍历每一个元素,分别对每个元素做如下处理:
先判断哈希表中是否存在这个元素,如果存在,直接返回;否则,将这个元素加入到哈希表中,方便后续的判重。
代码如下:
public int findRepeatNumber(int[] nums)
{
Set<Integer> set=new HashSet<>();//初始化哈希表
for(int i=0;i<nums.length;i++)
{
if(set.contains(nums[i]))//判断当前元素是否存在于哈希表中
{
return nums[i];
}
set.add(nums[i]);//否则添加进哈希表中
}
return -1;
}
结果:通过。
时间复杂度为O(n),空间复杂度为O(n)。
方案三:数组代替哈希表
根据题意中的,数组中每个元素的大小在0~n-1的范围内,利用数组代替上面的哈希表。(本人还不了解哈希表,不懂原理,所以直接上代码)。
代码如下:
public int findRepeatNumber(int[] nums)
{
int[] bucket=new int[nums.length];
Arrays.fill(bucket,-1);
for(int i=0;i<nums.length;i++)
{
if(bucket[nums[i]]!=-1)//判断当前元素是否存在(以旧数组元素值作为下标的新数组的元素,是否被改写过为判断的依据)
{
return nums[i];
}
bucket[nums[i]]=i;//否则的话,将当前旧数组元素作为新数组的下标,旧数组下标作为新数组的元素进行新数组改写。
}
return -1;
}
替换空格
题目描述
请实现一个函数,把字符串 s 中的每个空格替换成"%20"
限制:0 <= s 的长度 <= 10000
题目分析:此题需要注意的是:空格是一个字符,而“%20”是两个字符,因此不能用普通的替换法。
网上题解
**思路:**先统计空格个数,算出出参大小。(注意字符串结尾符,要多申请一个byte);再次遍历,将空格替换成%20
关于字符串结尾符,为什么要多申请一位的原因:
char src[11] ="abcdefghij";//只有10个字符,但字符串却开了11个空间,因为给‘\0’留位置了,最后一位是‘\0’
char src[] = "abcdefghij";//同上
char src[10] ="abcdefghij";//对于这个代码,字符串最后一位并不是‘\0’,而是j,因为字符串只开了10个空间,没有给‘\0’留位置。
对于题目中事先给定的字符串s,他默认是给‘\0’留位置了,所以要多申请一位。
代码如下
char*replaceSpace(char* s)
{
int i,j,len=strlen(s),cnt=0;
char *ans;
for(i=0;i<len;i++)
{
if(s[i]==' ')
{
cnt++;//计数需要扩充的空间个数
}
}
ans=malloc(sizeof(char)*(len+cnt*2+1));//扩充后的的内存大小
j=0;
for(i=0;i<len;i++,j++)
{
ans[j]=s[i];
if(s[i]=='')
{
ans[j++]='%';//关于j++ => 先用j,之后再将j+1
ans[j++]='2';//同上
ans[j]='0';
/* 与上述代码相同原理
ans[j] = '%';
j++;
ans[j] = '2';
j++;
ans[j] = '0';*/
}
}
ans[j]='\0';
return ans;
}