leetcode-Container With Most Water
来源:互联网 发布:广州淘宝二手汽车网 编辑:程序博客网 时间:2024/06/05 08:51
题目
Given n non-negative integers a1, a2, …, an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.
Note: You may not slant the container.
一开始的代码
nt maxArea(int* height, int heightSize) { int max = 0; if(heightSize == 0 || heightSize == 1){ return 0; } for(int i = 0; i < heightSize; i++){ for(int j = i + 1; j < heightSize; j++){ int row = j - i; int col = height[j] < height[i] ? height[j] : height[i]; int area = row * col; max = max > area ? max : area; } } return max;}
复杂度为O(N2)超时了
2.0版本,还是超时,不过不是之前的超时用例了
int maxArea(int* height, int heightSize) { int max = 0; if(heightSize == 0 || heightSize == 1){ return 0; } for(int i = 0; i < heightSize; i++){ if(i <= heightSize / 2){//距离右端远 int j = heightSize - 1; while(j > i){//从右开始,找到高度大于i的第一个也是最远的j if(height[j] >= height[i]){ //printf("%d * %d | ", height[i], j -i); max = max > (height[i] * (j - i)) ? max : height[i] * (j - i); break; } else{ j--; } } if(j - i < i){//右端的距离小于左端最远的距离,则左端可能存在大于目前面积的列,检查左端 int k = 0; while(k < i && i - k > j - i){ if(height[k] >= height[i]){ //printf("%d * %d | ", height[i], i-k); max = max > (height[i] * (i - k)) ? max : height[i] * (i - k); break; } else{ k++; } } } } else{//距离左端远,同上 int j = 0; while(j < i){ if(height[j] >= height[i]){ //printf("%d * %d | ", height[i], i-j); max = max > (height[i] * (i - j)) ? max : height[i] * (i - j); break; } else{ j++; } } if(i - j < heightSize - i - 1){ int k = heightSize - 1; while(k > i && k - i > i - j){ if(height[k] >= height[i]){ //printf("%d * %d | ", height[i], k -i); max = max > (height[i] * (k - i)) ? max : height[i] * (k - i); break; } else{ k--; } } } } } return max;}
3.0版,想到在上个版本上更进一步的简便方法,循环时多加个判断条件,可以少判断几次
int maxArea(int* height, int heightSize) { int max = 0; if(heightSize == 0 || heightSize == 1){ return 0; } for(int i = 0; i < heightSize; i++){ if(height[i] == 0){ continue; } if(i <= (heightSize - 1) / 2){//距离右端远 int j = heightSize - 1; while(j > i && ((j - i) > max / height[i])){//从右开始,找到高度大于i的第一个也是最远的j if(height[j] >= height[i]){ //printf("%d * %d | ", height[i], j -i); max = max > (height[i] * (j - i)) ? max : height[i] * (j - i); break; } else{ j--; } } if(j - i < i){//右端的距离小于左端最远的距离,则左端可能存在大于目前面积的列,检查左端 int k = 0; while(k < i && i - k > j - i){ if(height[k] >= height[i]){ //printf("%d * %d | ", height[i], i-k); max = max > (height[i] * (i - k)) ? max : height[i] * (i - k); break; } else{ k++; } } } } else{//距离左端远,同上 int j = 0; while(j < i && ((i - j) > max / height[i])){ if(height[j] >= height[i]){ //printf("%d * %d | ", height[i], i-j); max = max > (height[i] * (i - j)) ? max : height[i] * (i - j); break; } else{ j++; } } if(i - j < heightSize - i - 1){ int k = heightSize - 1; while(k > i && k - i > i - j){ if(height[k] >= height[i]){ //printf("%d * %d | ", height[i], k -i); max = max > (height[i] * (k - i)) ? max : height[i] * (k - i); break; } else{ k--; } } } } } return max;}
还是未通过,当测试用例为倒序时,遍历的次数还是会较多,因此改下算法,先算下用例大概为升序还是降序,若为升序则从左向右开始遍历,若为降序,则从右开始向左遍历。
改完了,还是未过…只好根据测试用例,采用暴力破解了
int maxArea(int* height, int heightSize) { int max = 0; if(heightSize == 0 || heightSize == 1){ return 0; } int asc = 1; for(int i = 1; i < heightSize; i++){ if(height[i] < height[i - 1]){ asc = 0; break; } } if(asc == 1){//升序数列 for(int i = 0; i < heightSize; i++){ max = max > (heightSize - i - 1) * height[i] ? max : (heightSize - i - 1) * height[i]; } return max; } int desc = 1; for(int i = 0; i < heightSize; i++){ if(i == heightSize - 1){ if(height[i] > height[i - 1]){ desc = 0; break; } } else{ if(height[i] < height[i + 1]){ desc = 0; break; } } } if(desc == 1){ for(int i = heightSize - 1; i >= 0; i--){ max = max > i * height[i] ? max : i * height[i]; } return max; } if(asc >= 0){ for(int i = 0; i < heightSize; i++){ if(height[i] == 0){ continue; } if(i <= (heightSize - 1) / 2){//距离右端远 int j = heightSize - 1; while(j > i && ((j - i) > max / height[i])){//从右开始,找到高度大于i的第一个也是最远的j if(height[j] >= height[i]){ //printf("%d * %d | ", height[i], j -i); max = max > (height[i] * (j - i)) ? max : height[i] * (j - i); break; } else{ j--; } } if(j - i < i){//右端的距离小于左端最远的距离,则左端可能存在大于目前面积的列,检查左端 int k = 0; while(k < i && i - k > j - i){ if(height[k] >= height[i]){ //printf("%d * %d | ", height[i], i-k); max = max > (height[i] * (i - k)) ? max : height[i] * (i - k); break; } else{ k++; } } } } else{//距离左端远,同上 int j = 0; while(j < i && ((i - j) > max / height[i])){ if(height[j] >= height[i]){ //printf("%d * %d | ", height[i], i-j); max = max > (height[i] * (i - j)) ? max : height[i] * (i - j); break; } else{ j++; } } if(i - j < heightSize - i - 1){ int k = heightSize - 1; while(k > i && k - i > i - j){ if(height[k] >= height[i]){ //printf("%d * %d | ", height[i], k -i); max = max > (height[i] * (k - i)) ? max : height[i] * (k - i); break; } else{ k--; } } } } } } else{printf("new algo"); for(int i = heightSize - 1; i >= 0 ; i--){ if(height[i] == 0){ continue; } if(i >= (heightSize - 1) / 2){ int j = 0; while(j < i && (i - j) > max / height[i]){ if(height[j] >= height[i]){ max = max > (height[i] * (i - j)) ? max : height[i] * (i - j); break; } else{ j++; } } if(i - j < heightSize - i - 1){ int k = heightSize - 1; while(k > i && k - i > i - j){ if(height[k] >= height[i]){ max = max > (height[i] * (k - i)) ? max : height[i] * (k - i); break; } else{ k--; } } } } else{ int j = heightSize - 1; while(j > i && ((j - i) > max / height[i])){//从右开始,找到高度大于i的第一个也是最远的j if(height[j] >= height[i]){ //printf("%d * %d | ", height[i], j -i); max = max > (height[i] * (j - i)) ? max : height[i] * (j - i); break; } else{ j--; } } if(j - i < i){//右端的距离小于左端最远的距离,则左端可能存在大于目前面积的列,检查左端 int k = 0; while(k < i && i - k > j - i){ if(height[k] >= height[i]){ //printf("%d * %d | ", height[i], i-k); max = max > (height[i] * (i - k)) ? max : height[i] * (i - k); break; } else{ k++; } } } } } } return max;}
观察测试用例,发现超时的用例要么是升序,要么是降序,因此,在最开始判断用例是升序还是降序,然后相应的遍历一次解决…
嗯,这是个投机取巧的方法,纯粹只是为了通过题目而已..
不过根据原来的算法,其实也才300ms左右,也算过了吧~哈哈
代码中我觉的有大量冗余的地方,但是懒得改了,就放在那里了
0 0
- LeetCode: Container With Most Water
- [LeetCode]Container With Most Water
- LeetCode Container With Most Water
- LeetCode: Container With Most Water
- [Leetcode] Container With Most Water
- Leetcode: Container With Most Water
- [LeetCode] Container With Most Water
- LeetCode Container With Most Water
- [Leetcode] Container With Most Water
- [LeetCode]Container With Most Water
- LeetCode-Container With Most Water
- Container With Most Water leetcode
- LeetCode - Container With Most Water
- LeetCode: Container With Most Water
- Leetcode: Container With Most Water
- 【LeetCode】Container With Most Water
- Leetcode: Container With Most Water
- LeetCode:Container With Most Water
- Linux之线程和进程及进程间通信
- Shell函数参数
- JDBC编程的步骤
- 【BZOJ】3389: [Usaco2004 Dec]Cleaning Shifts安排值班
- 杀死某用户的会话
- leetcode-Container With Most Water
- Spring MVC Controller单例陷阱
- 评论功能
- Jboss rules规则引擎 Drools 6.4.0 Final 教程(1)
- 解决大数组定义时栈溢出的两种方法
- Android Studio 和 Esclipse 获取SHA1
- 2016关于职场的几条真理(中)
- boost程序库学习-lexical_cast
- Unity中的优化技术