首尾指针法简单小结

以一道题目的优化过程来浅显的说一说首尾指针法
这是一道leetcode的题目
我之前的博客记录过

在这里插入图片描述
博客中我的做法就是比较常规的记录每个位置的左右最大值

1.第一种优化
只用一个数组记录每个位置右边最大值,不记录左边最大值,左边最大值用一个变量来记录即可,这样节省了空间,其他步骤相同

2.第二种优化,使用首尾指针
大体逻辑延续上面的做法,首尾两个位置是不可能有雨水装的。
首尾指针怎么做,逻辑如下:分别记录左右指针左右两边的当前最大值,然后每次解决左右最大值中的较小值并移动左或右指针。
为什么能这么做(正确性?)?
举例,比如当前左指针左边最大值比右指针右边最大值小,那么对于左指针,当前左边最大值已知并且是确定的因为指针从左到右移动,虽然中间仍有很多数没有遍历到,但不影响结果的正确性,因为右指针右边的最大值比左指针左边最大值大,所以中间的数的最大值必然大于等于右指针右边最大值,所以左指针当前位置是可以计算得出结果的(不管能不能装水),然后更新左指针左边最大值并移动左指针。右指针同理
代码:

public static int water4(int[] arr) {
	if (arr == null || arr. length < 2) {
		return 0;
	}
	int N = arr.length;
	int L= 1; 
	int leftMax = arr[0]; 
	int R=N-2; 
	int rightMax = arr[N -1]; 
	int water =0; 
	while (L <= R) {
		if (leftMax <= rightMax) {
			water += Math. max(0, leftMax -arr[L]); 
			leftMax = Math.max(leftMax,arr[L++]);
		} else {
			water += Math. max(0, rightMax -arr[R]); 
			rightMax =Math. max(rightMax, arr[R--]);
	}
	return water
}

总结:

1.能用首尾指针技巧解决的问题,往往序列是存在规律的,但其实这种要求并不严格,不一定要有序!!
2.但是要求首尾指针根据制定的规则往中间移动的过程中确保移动过的数之后不再影响答案并不会错过答案
3.制定的规则与数据状况和问题本身有关(需要分析具体问题,一点点灵感)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值