
🔥近津薪荼:个人主页
🎬个人专栏:《c语言基础知识详解》《c++基础知识详解》《Linux操作系统及网络基础知识分享》《近津薪荼的算法日迹》
脚长在自己身上,
走不走,走哪条路,走什么样的路自己决定。
做不做人,做什么样的人亦是如此。
想走的路不好走,想做的人又不好做,都说是身不由己,
这不是废话吗?
已不由心,身又岂能由己?
------张之为
本期知识点导图:
1.上期参考代码
cpp
class Solution {
public:
int bitsum(int n)
{
int sum=0;
while(n)
{
int t=n%10;
sum+=t*t;
n/=10;
}//每一次操作的逻辑,取出每一位,乘方后相加
return sum;
}
bool isHappy(int n) {
int slow=n,fast=bitsum(n);//定义快慢指针,快指针快一步,因为下边要进行逻辑判断
while(slow!=fast)
{
slow=bitsum(slow);
fast=bitsum(bitsum(fast));//快指针一次走两步
}
return fast==1;//返回值是这个表达式的值
}
};
上期的重点是理解双指针的特殊用法,将值本身作为双指针。逻辑上不是很难,主要是概念有点抽象。不懂的同学积极在评论区和大家互动哈~
期待批评指正~
2.本期题目解析

要点:
简单说来就是简化版的短板装水问题
数组里面的元素对应各个板子的高度
底的长度等于所选两个板子(数组元素)的下标之差
盛水量=短板高度x底
题给示例中,短板高度为7,两个元素的下标分别是1和8,差为7。盛水量为49。
3.解题思路
3.1暴力解法
两个for循环嵌套,穷举所有组合,得到所有组合的结果,然后取最大值
时间复杂度为O(N^2),虽然测试用例能对,但是判题结果为超时。
代码:
cpp
class xxj {
public:
int maxArea(vector<int>& height) {
int n=height.size(),s=0;
for(int i=0;i<n;i++)
{
for(int j=1;j<n;j++)
{
int tmp=min(height[i], height[j])*(j-i);
if(tmp>s)
s=tmp;
}
}
return s;
}
};


3.2优解思路
暴力解法,去穷举了所有情况,进行了很多不必要的计算,那我们接下来要讲的思路就是想办法省去不必要的计算,也就是选择性地进行计算~
3.2.1题目解析中,我给出的算式包含2个自变量,如何表示?

- 短板高度,由双指针指 向的元素比较大小,取小得到。
- 底为双指针指 向元素下标之差。
3.2.2逻辑
我们在数组中任意取一段区间,就拿题给示例来说:

- 定义双指针分别指向左右两端。
- 计算出V之后,要开始**遍历数组,**用合适的方法枚举体积,并找到最大值。
怎么遍历?
在前边讲到的暴力解法中,两个for循环,走内层循环的时候,j单向向后 走,i不变。走外层循环的时候,i单向向后 走。每一个i位置元素都要和后边所有元素组合一次,不对元素作逻辑判断。

我们把j指针放到数组最后,并让它从后往前遍历,也就是把i和j变成从两端向内遍历的双指针left和righjt。这是常用的双指针遍历方式,是大家必须要掌握滴~
在这种遍历方式的前提下,我们对双指针指向的元素进行逻辑判断,通过判断结果,来减少不不要的遍历步骤,减少计算量。
观察遍历过程
不难发现W是一直在减小的(向内遍历)。
第一次移动指针,如果移动长板 ,短板的高度是不会增大的。(单调性)

所以移动指向长板的指针是无用 的计算(得不到更大的值),应该省去。
也就是说,遍历的过程,在算出上一次的体积之后,应该移动指向短板的指针进行下一次体积的运算。
按照这个逻辑,我们试试看~

上述方法能在所取的小区间里找到V的最大值。那么把区间范围扩大到全体,亦然。
思路讲到这里就结束了,练去吧~~
4.预告~
下期要讲解的题目是:
我们下期再见~
ps:yidingyaozijidongshoucahngshiyixia!