码迷,mamicode.com
首页 > 其他好文 > 详细

[LeetCode]Array主题系列

时间:2018-03-02 18:49:56      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:point   效率   部分   note   高度   img   ant   res   循环   

 

1.内容介绍

 

开一篇文章记录在leetcode中array主题下面的题目和自己的思考以及优化过程,具体内容层次按照{题目,分析,初解,初解结果,优化解,优化解结果,想法}的格式来记录,供日后复习和反思。题目的顺序按照leetcode给出的题目顺序,有些题目在并不是按照题目本身序号顺序排列的,也不是严格按照难易程度来排列的。

因此,这篇文章并不具有很强的归类总结性,归类总结性知识将会在其他文章记录,本篇重点在记录解题过程中的思路,希望能对自己有所启发。

2.题目和解题过程

2.1 Container With Most Water

  • 题目:Given n non-negative integers a1a2, ..., an, where each represents a point at coordinate (iai). n vertical lines are drawn such that the two endpoints of line i is at (iai) 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 and n is at least 2. 
  • 分析:要找到能容纳最多水的容器,等价目标是使得两条线之间面积最大(右图所示红线之间的面积),面积计算公式是:ax * |i-j|, ax是{ai,aj}中较小的一方,|i-j|是两条线之间的距离,因此可以知道面积的大小受到线的高度和两条线之间的距离的影响。技术分享图片
  • 初解:设置一个变量初始化最大面积值为0,从最左边的一条线开始向右迭代,跳过高度为0的线,对于迭代的每条线分别计算与其右边的每一条线进行计算区域面积,跳过高度为0的线,然后与当前最大面积比较,记录下最大面积值。该解法的时间复杂度是O(n2),空间复杂度是O(1)。
    class Solution {
    public:
        int maxArea(vector<int>& height) {
            int area = 0;
            int max_height = 0;
            for(int i = 0; i < height.size(); ++i)
            {
                while(height[i]==0 && i < height.size())
                    ++i;
                for(int j = i+1 ; j < height.size(); ++j)
                {
                    while(height[j]==0 && j < height.size())
                        ++j;
                    if(j < height.size())
                    {
                        int a = (height[i] < height[j])? height[i]:height[j];
                        int tmp_area = a * (j - i);
                        if(tmp_area > area)
                            area = tmp_area;    
                    }
                }
                if(height[i] > max_height)
                    max_height = height[i];
            }
            return area;
        }
    };
  • 初解结果:技术分享图片
  • 优化解法:显然,初解的思路是对的,仅仅是效率不够高,在输入规模较大时,完全双层循环的O(n2)时间复杂度不能满足要求。但是由于目标面积受两个因素{高度,距离}的影响,因此我们可以尝试在这两个因素上做过滤检查,省去一些不必要的计算。首先,针对高度优化可以做如下考虑:在外层循环上当前线(i,ai)上做完计算后,如果后面的线(k,ak)的高度ak比ai小,那么计算出来的面积一定不会超过在ai上计算的最大面积,因此可以过滤这些线。其次,针对距离优化可以做如下考虑:每次向后移动完外层循环的线后,开始确定内层循环的起始线时,跳过在当前外层线的高度下取得最大面积必须的距离,这样的话就能省去部分计算。
    class Solution {
    public:
        int maxArea(vector<int>& height) {
            int area = 0;
            int max_height = 0;
            for(int i = 0; i < height.size(); )
            {
                while(height[i]==0 && i < height.size())
                    ++i;
                int j = (area == 0)?(i+1):(i + area / height[i]);
                for( ; j < height.size(); ++j)
                {
                    while(height[j]==0 && j < height.size())
                        ++j;
                    if(j < height.size())
                    {
                        int a = (height[i] < height[j])? height[i]:height[j];
                        int tmp_area = a * (j - i);
                        if(tmp_area > area)
                            area = tmp_area;    
                    }
                }
                if(height[i] > max_height)
                    max_height = height[i];
                int next_index = i+1;
                while(next_index < height.size() && height[next_index] <= max_height)
                    ++next_index;
                i = next_index;
            }
            return area;
        }
    };
  • 优化结果:仅仅优化高度时的结果:技术分享图片

    再加上距离优化的结果:技术分享图片

  • 反思:求解题目时如果搜索范围较广,且不能修改搜索框架时,较好的方法是做条件过滤,去除明显不可能计算出所求结果的候选值,用于加速计算过程。

[LeetCode]Array主题系列

标签:point   效率   部分   note   高度   img   ant   res   循环   

原文地址:https://www.cnblogs.com/burningTheStar/p/8494159.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!