数组墙
- 题目
给定一个正整数数组如[2,5,1,2,3,4,7,7,6],数组中每个数代表一个墙的高度,如图,
- 分析
一开始我想的太复杂了,时间复杂度都到了O(n*log n),后来看了陈老师的解释的时间复杂度为O(n),心里挺佩服的。后就不看解释了,自己想,想好算法后,开始写代码,调了一下午,发现算法考虑的情况不全,当时心痛呀,那个痛呀。今天上午仔细看了一下陈老师的分析。感觉一个字“棒”。特意整理一下,供大家参考。
我们拿个例子来说吧
陈老师的解法:
有如下标识符
例子数据,并且标识初始化如下
然后开始双向遍历数组(直至整个数组都遍历完毕才结束)。
比较当前LM和RM,发现 LM<RM,然后LI向右移动一个单位,如下
当前LI指向的数据比LM指向的数据大,则更新LM为当前LI。如下
然后接着比较当前的LM和RM,发现LM>RM,则RI向左移动一位,如下
比较RI不比RM大,所以不更新RM,这时候证明RI可以存水,存水量即 (11 - 1 ) = 10。
然后接着比较当前的LM和RM,发现LM>RM,则RI向左移动一位,如下
接着发现RI可以存水,然后计算存水的量。
然后LM<RM,RI继续左移,如下
发现RI也可以存水,并计算存水的量,
然后继续比较LM<RM,RI继续左移,此时RI不比RM大,RM不更新,继续计算RI的存水量。如下
接着LM<RM,RI左移,如下
发现RI>RM,则更新RM ,此时RI不能存水,如下
到这相信大家都明白了吧,汉字我就不多说了,直接看图走过程吧
接着最后RI = LI,整个数组遍历完毕,算法结束,所有的存水量加起来就是 结果啦。
- 实验
- 代码
test.cpp
#include<iostream>
using namespace std;
size_t const size = 10;
//function declare
int Run(int data[],int length);
int main()
{
int * data = new int[size];
cout<<"array wall :";
for(size_t i = 0; i<size; i++)
{
data[i] = rand()%19;
cout<<data[i]<<" ";
}
cout<<endl<<"water ";
cout<<Run(data,size)<<endl;
system("pause");
return 0;
}
int Run(int data[],int length)
{
if(data == NULL && length < 3)
{
return 0 ;
}
int left_index = 0;
int right_index = length - 1 ;
int left_max = data[left_index];
int right_max = data[right_index];
int count = 0;
while( left_index < right_index )
{
if( left_max < right_max )
{
left_index ++ ;
if( data[left_index] > left_max )
{
left_max = data[left_index];
}
else
{
count += left_max - data[left_index];
}
}
else
{
right_index --;
if(data[right_index] > right_max)
{
right_max = data[right_index];
}
else
{
count += right_max -data[right_index];
}
}
}
return count ;
}
再次感谢陈利人老师的题目!!!
#include<iostream>
using namespace std;
size_t const size = 10;
//function declare
int Run(int data[],int length);
int main()
{
int * data = new int[size];
cout<<"array wall :";
for(size_t i = 0; i<size; i++)
{
data[i] = rand()%19;
cout<<data[i]<<" ";
}
cout<<endl<<"water ";
cout<<Run(data,size)<<endl;
system("pause");
return 0;
}
int Run(int data[],int length)
{
if(data == NULL && length < 3)
{
return 0 ;
}
int left_index = 0;
int right_index = length - 1 ;
int left_max = data[left_index];
int right_max = data[right_index];
int count = 0;
while( left_index < right_index )
{
if( left_max < right_max )
{
left_index ++ ;
if( data[left_index] > left_max )
{
left_max = data[left_index];
}
else
{
count += left_max - data[left_index];
}
}
else
{
right_index --;
if(data[right_index] > right_max)
{
right_max = data[right_index];
}
else
{
count += right_max -data[right_index];
}
}
}
return count ;
}