268.缺失数字
我的思路:
- 排除特殊情况,若是判断数组为空或长度为0,则直接返回0
- 将给定数组排序
- 循环遍历数组,范围是从0到(nums-1)
- 比较当前索引对应的值和索引是否相等,若不相等,则返回当前索引,即为数组中缺失的值
- 若循环顺利,则说明数组前面不缺数字,只能是最后却少一个,正好是 i,所以返回 i
对应程序
public int missingNumber(int[] nums) {
//1
if(nums == null || nums.length == 0) {
return 0;
}
//2
Arrays.sort(nums);
//3
int i = 0;
for (; i < nums.length; i++) {
//4
if(nums[i] != i ) {
return i;
}
}
//5
return i;
}
上面这个方法虽然得到了答案,但是在lectcode的执行用时中:11 ms, 在所有 Java 提交中击败了24.92%的用户!
于是我就想着去评论区看看别人怎么写,我就发现了一条评论,写着求和公式,当时我就如晴天霹雳,怎个人懵了,竟然还可以这样,然后就是恍然大悟,自己写出了下面的解法:
其他思路
- 定义一个变量,用来求数组所有元素的和
- 循环遍历求出和
- 返回 (1+nums.length)*nums.length/2 -num
对应程序
public int missingNumber(int[] nums) {
//1
int num = 0;
//2
for(int i=0;i<nums.length;i++) {
num += nums[i];
}
//3
return (1+nums.length)*nums.length/2-num;
}
有的人可能看着上面的第三条思路有点懵,哈哈哈,别急听我给你仔细道来
既然一个数组它只缺少一个元素,那我们是不是就可以求得他不缺少元素的和呢??
举个例子:
完整的数组:【0,1,2,3,4,5,6】
所给的数组:【0,1, ,3,4,5,6】
求和公式:(首项 + 末相)* 项数 / 2
我们可以通过求和公式求出完整数组的和,(因为加0等于没加,所以可以取掉0)而首相就是1,末项就是nums.length,项数也是nums.length(取0后项数正好是nums.length)。而缺少的就是完整数组的和减去所给数组的和!!
283.移动零
我的思路:
这个题用插入排序的思路,将0全部插入到数组尾部即可
- 循环遍历整个数组
- 判断此时的元素是否为0
2.1 若是为0,则将后面的元素用循环依次往前移动,最后将0插入在最后一个
2.2若是不为0,则遍历下一个元素
(ps:这个思路一定要注意第一层循环遍历的条件要设为一个变量,当元素为0插入数组尾部后,将变量减一,不然当循环到尾部时,会成为死循环)
对应程序
public void moveZeroes(int[] nums) {
//1
int a = nums.length;
for(int i=0;i<a;) {
//2.1
if(nums[i] == 0) {
int temp = nums[i];
int j=i;
for(;j<nums.length-1;j++) {
nums[j] = nums[j+1];
}
nums[j] = temp;
a--;
}
//2.2
else {
i++;
}
}
}
虽然用插入排序很好写,但是还是老问题,时间复杂度太高,所以又去发现了一种新解法
其他思路
- 得到数组中非零元素的个数num
- 将数组的前num项按顺序替换为数组中的非零元素
- 将数组中剩余的位置用0替代
public void moveZeroes(int[] nums) {
//1
int index = 0;
for(int i=0;i<nums.length;i++) {
//2
if(nums[i] != 0) {
nums[index] = nums[i];
index++;
}
}
//3
for(int i=index;i<nums.length;i++) {
nums[i] = 0;
}
}
这样写出来后,瞬间时间复杂度就降低了好多,所以以后在遇到题,一定要多思考,看是不是又更好的解法,尽量达到自己能力范围内的最优解
169.找众数
我的思路:
首先先将数组排序,在定义一个变量,循环遍历数组,将相同数的个数累计,若是个数大于n/2则返回这个数
- 数组排序
- 定义一个变量用于相同数的计数
- 循环遍历整个数组
- 若是循环到数组的最后一个元素,还没有求出众数,则直接返回最后一个数(题目假设给定数组必有众数)
- 若不是最后一个元素,则判断是否与后一个元素相等,不相等再判断这个元素的个数是否大于n/2,大于就直接返回此元素
public int majorityElement(int[] nums) {
//1
Arrays.sort(nums);
//2
int index = 0;
//3
for(int i=0;i<nums.length;i++) {
index++;
//4
if(i+1 == nums.length) {
return nums[i];
}
//5
else if(nums[i] != nums[i+1]) {
if(index>nums.length/2) {
return nums[i];
}
index = 0;
}
}
return 0;
}
本题的思想又叫蠕虫思想,就是循环一遍看相等的元素的长度,若是大于n/2就是那个元素!