寒假每日一题打卡专栏已经结束了,今天开始剑指offer专栏。
【题目描述】
解法一: 开辟数组统计数字出现次数
【思路】
时间复杂度: 扫描数组 O(n)
空间复杂度: 开辟额外空间 O(n)
class Solution {
public int duplicateInArray(int[] nums) {
//数据范围0 ~ n - 1
int n = nums.length;
int f[] = new int[n];
for(int i = 0; i < n; i ++){
int a = nums[i];
//如果某些数字不在 0∼n−1 的范围内, 则返回 -1
if( a < 0 || a >= n) return -1;
f[a] ++;
}
for(int i = 0; i < n; i ++)
if(f[i] > 1) return i;
//数组中不包含重复数字,则返回 -1
return -1;
}
}
解法二
【思路】
移动元素让下标与元素值相等
时间复杂度: 扫描数组 O(n)
空间复杂度: O(1)
class Solution {
public int duplicateInArray(int[] nums) {
if( nums == null || nums.length <= 1) return -1;
//遍历数组
int n = nums.length;
for(int i = 0; i < n; i ++)
//如果某些数字范围不在[0, n - 1] 之间
if( nums[i] < 0 || nums[i] > n - 1) return -1;
for(int i = 0; i < n; i ++){
//将i位置原本元素移动至正确位置
while( i != nums[i]){
if( nums[i] == nums[ nums[i] ] ) return nums[i];
int tmp = nums[ nums[i] ];
nums[ nums[i] ] = nums[i];
nums[i] = tmp;
}
}
return -1;
}
}
解法三:排序
【思路】
排序 : 相等的数必定相邻
class Solution {
public int duplicateInArray(int[] nums) {
if( nums == null || nums.length <= 1) return -1;
int n = nums.length;
for(int i = 0; i < n; i ++)
//如果某些数字范围不在[0, n - 1] 之间
if( nums[i] < 0 || nums[i] > n - 1) return -1;
Arrays.sort(nums);
for(int i = 1; i < n; i ++){
if( nums[i - 1] == nums[i] ) return nums[i - 1];
}
return -1;
}
}