leetcode刷题记录(268、283、169)

268.缺失数字

在这里插入图片描述
我的思路:

  1. 排除特殊情况,若是判断数组为空或长度为0,则直接返回0
  2. 将给定数组排序
  3. 循环遍历数组,范围是从0到(nums-1)
  4. 比较当前索引对应的值和索引是否相等,若不相等,则返回当前索引,即为数组中缺失的值
  5. 若循环顺利,则说明数组前面不缺数字,只能是最后却少一个,正好是 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. 定义一个变量,用来求数组所有元素的和
  2. 循环遍历求出和
  3. 返回 (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全部插入到数组尾部即可

  1. 循环遍历整个数组
  2. 判断此时的元素是否为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++;
		}
	}
 }

        虽然用插入排序很好写,但是还是老问题,时间复杂度太高,所以又去发现了一种新解法

其他思路

  1. 得到数组中非零元素的个数num
  2. 将数组的前num项按顺序替换为数组中的非零元素
  3. 将数组中剩余的位置用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则返回这个数

  1. 数组排序
  2. 定义一个变量用于相同数的计数
  3. 循环遍历整个数组
  4. 若是循环到数组的最后一个元素,还没有求出众数,则直接返回最后一个数(题目假设给定数组必有众数)
  5. 若不是最后一个元素,则判断是否与后一个元素相等,不相等再判断这个元素的个数是否大于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就是那个元素!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值