题目
思路
emmm小学奥数题的感觉,希望以后可以适应好这样的题目。思维比较慢,希望以后有快速思考和编程的能力。
面试题或者说实际生产的程序算法设计,需要的是人为简化,就像给孩子铺路一样,能帮的事情都给帮了。这里面最有用的简化是复杂度的简化,目前比较理解的是对于循环的缩减。其次可以缩减一些较为明显的步骤,比如判断句这样的,判断一次可以少执行很多次语句,对于复杂度可能没什么大影响,但终归是节省了计算量。
秉承着这样的想法,我考虑到了这样几个关键点:
- 末项距首项最远
- 遍历套遍历和遍历并发
技术回顾
都忘干净了……
vector
操作上类似于动态可变长的数组,(本质区别在于运行和存储的方式)。primer的作者说,“在实际的编程中,我们作为程序员应该避免用到低级数组和指针,而更应该多用高级的vector和迭代器。”
这里需要用到的有
- vector<数据类型> 名称
- 名称.push_back :存入
- 名称.size():长度
- 名称 [ i ]:取数
三目运算符
a>b ? 左 :右
角标运算
间隔:两脚标作差即可。
倒数第n个数:N-n. 如:最后一个是[N-1],倒数第三个是[N-3]。
第n个数:n-1。
移动n个数(n次):+ - n 。
数组置空
int array[number] = { }; // int类型表现形式是 0 。
一点代码简化
- 循环第一步不要提出来,显得啰嗦。如果第一步属于特殊情况,建议垫一步而不是拆出来,这样比较工整。
- while(height[ai]<=h) ai++; 等号的作用使循环不卡。
O(n²)代码如下:主从动型
class Solution
{
public:
int maxArea(vector<int> &height)
{
int area = 0;
int number = height.size();
int archive[number] = {};
for (int i = 0; i < number - 1; i++)
{
if (height[number - 1] >= height[i])
{
archive[i] = (number - 1 - i) * height[i];
}
else
{
int temp = height[number - 1];
int temparea = temp * (number - 1 - i);
for (int k = 0; k < number - 1 - i; k++)
{
if (height[number - 1 - k] <= temp)
continue;
else
{
int heightplus=height[i]<height[number - 1 - k]? height[i]:height[number - 1 - k];
if (temparea > heightplus * (number - 1 - k-i))
continue;
else
{
temp = height[number - 1 - k];
temparea = heightplus * (number - 1 - k-i);
}
}
}
archive[i] = temparea;
}
}
for (int i = 0; i < number - 1; i++){
cout<<archive[i]<<" ";
area = archive[i] > area ? archive[i] : area;
}
return area;
}
};
O(n)代码如下:并发动型
class Solution{
public:
int maxArea(vector<int> &height){
int ai=0;
int an=height.size()-1;
int water=0,h=0;
while(an>ai){
h=min(height[ai],height[an]);
water=max(water,h*(an-ai));
while(height[ai]<=h) ai++;/*12=**/
while(height[an]<=h) an--;
}
return water;
}
};