刷题一个4ms的程序,代码如何优化到3ms再到2ms?

举报
bigsai 发表于 2021/02/03 02:04:14 2021/02/03
【摘要】 目录 前言具体结语 如果觉得本文有所帮助,记得点赞收藏! 前言 你在打王者荣耀的时候,是否经常会遇到这种情况:和对面同位置对线的时候,自己也没有太大失误,但是为啥对面经济比我高?能够压着我打?——是我太菜了 这可能就是你们细节上的差距,别人可能对兵线、技能、英雄机制搞得更清楚,每一步都清清楚楚,刷题也是一样,同样的方法,...

如果觉得本文有所帮助,记得点赞收藏

前言

你在打王者荣耀的时候,是否经常会遇到这种情况:和对面同位置对线的时候,自己也没有太大失误,但是为啥对面经济比我高?能够压着我打?——是我太菜了

这可能就是你们细节上的差距,别人可能对兵线、技能、英雄机制搞得更清楚,每一步都清清楚楚,刷题也是一样,同样的方法,为啥别人的比你快很多,也需要注意一下细节。

在这里插入图片描述

笔者最近再刷LeetCode,对于正常一道题来说,时间的耗费有两个差距:

时间复杂度的差距

时间复杂度上的差距,因为很多题正常的暴力是O(n2)甚至更慢的时间复杂度,这些方法就算能过但是时间耗费很长,如果你发现你的算法过的时间在后30%那就说明你的方法不对了。在复杂度的差距差的可能几百毫秒,几十毫秒,而快的可能是几毫秒。

细节上的差距
很多题可能大家能够想到的比较好的方法的时间复杂度可能差不多,自己也是几毫秒但是自己的排名依然在50%-60%左右,这到底是为什么呢?是因为你的细节还需要优化,你整体复杂度虽然掌握了,但是你可能多算了几次循环,几次运算。所以当条件允许你需要静下来思考下怎么样才能让自己的程序跑在前90%以上。怎样去优化这个时间。
在这里插入图片描述

具体

笔者就拿今天刷的这道力扣题来讲讲,力扣的第11题,思路很清晰就是从两边向中间动态压缩区间,是一个O(n)的时间复杂度。

笔者第一次使用这个写法是4ms:

public int maxArea2(int[] height) {
		int max = 0;
		int left = 0;
		int right = height.length - 1;
		while (left < right) { max = Math.max(max, Math.min(height[left], height[right]) * (right - left)); if (height[left] > height[right])// 右侧更小 right--; else { left++; }
		}
		return max;
	}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

在这里插入图片描述
但是我在研究这段代码时候发现以下几点问题可以优化:

  • 使用Math.max()判断最大值最小值的时候,下面在判断是左指针右移还是右指针左移动重复判断了,我们可以手动比较大小重复利用这次计算去完成相同的操作。
public int maxArea3(int[] height) {
	int max = 0;
	int left = 0;
	int right = height.length - 1;
	while (left < right) {
		if (height[left] < height[right]) { max = Math.max(max, height[left] * (right - left)); left++;
		} else { max = Math.max(max, height[left] * (right - left)); right--;
		}
	}
	return max;
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

这样的一部优化之后时间来到了稳定的3ms:
在这里插入图片描述

还能继续优化嘛?当然能:

  • Math.max()返回double类型转成int需要一定成本,然而我们数据本身就是int类型可以直接计算。
  • 对数组取值的时候,比较取一次(两个值),计算取一次(一个值),而我们知道数组其实在内存中我们通过0号位置计算得到我们对应位置的数值,所以我们可以把3次计算减少成2次,用两个空间leftvalue和rightvalue记录左右数组位置的值。

通过上面的优化得到下面的代码:

public int maxArea4(int[] height) {
		int max = 0;
		int left = 0;
		int right = height.length - 1;
		int team = 0;
		int leftvalue=0;int rightvalue=0;
		while (left < right)  { leftvalue=height[left];rightvalue=height[right]; if (leftvalue < rightvalue) { team = leftvalue * (right-left); if(max<team) {max=team;} left++; } else { team = rightvalue * (right-left); if(max<team) {max=team;} right--; }
		}
		return max;
	}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

成功步入2ms大军。

在这里插入图片描述
在这里插入图片描述
还能到1ms嘛?

  • 我是暂时不能了,,各位大佬请便!

结语

虽然这些优化并没有得到质的改善,并且可能也比较初级,但是刷题的同时通过这种不断优化能够增加对计算机执行和原理的理解:哇,原来是这样。并且如果有时间养成这样的好习惯,相信不就以后,未来的调优专家就是你了!

如果觉得不过,记得点赞关注哦!公众号:bigsai,回复bigsai获得笔者珍藏学习资源。

文章来源: bigsai.blog.csdn.net,作者:Big sai,版权归原作者所有,如需转载,请联系作者。

原文链接:bigsai.blog.csdn.net/article/details/108154831

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。