[leetcode-top100-medium]11.盛水最多的容器,15三数之和

目录

11. 盛最多水的容器 - 力扣(Leetcode)

 思路:

 15. 三数之和 - 力扣(Leetcode)

思路


11. 盛最多水的容器 - 力扣(Leetcode)

 思路:

这是典型的双指针解法,使用left指针指向数组的0下标,right指针指向数组的最后一个下标,写出盛水容积的关系式:Volume =min(height[left],height[right]) * (right-left),维护一个最大的容积maxVolume,maxVolume = max(maxVolume,volume),之后指针需要移动,移动的策略就是:
哪个指针对应的高度值小,移动哪一个指针,因为容积的约束条件是小的哪个指针对应的值。

python

class Solution:
    def maxArea(self, height: List[int]) -> int:
        # 双指针解法
        # 边界
        n = len(height)
        if n < 2:return 0
        maxVolume = 0
        left,right = 0,n-1
        while left < right:
            maxVolume = max(maxVolume,min(height[left],height[right]) * (right-left))
            if height[left] > height[right]:right -= 1
            else:left += 1
        return maxVolume

c++

class Solution {
public:
    int maxArea(vector<int>& height) {
        //双指针问题
        int maxVol = 0;
        int left = 0,right = height.size()-1;
        while (left < right){
            maxVol = max(maxVol,min(height[left],height[right]) * (right - left));
            if (height[left] < height[right]) left++;
            else right--;
        }
        return maxVol;
    }
};

 15. 三数之和 - 力扣(Leetcode)

思路

 第一道题太简单了,今天多做一道题。

这个问题的初始解法是使用三重循环遍历,但是这样时间复杂度是O(n^3),这样不好,写出来面试官也会让你优化的,所以这里使用的是排序+双指针的办法降低复杂度。

找一个三元组,三元组的下标不能相同,就是不能重复使用同一个元素,且三个元素的和为零。

这里可以先排序,排序之后遍历数组,遍历的元素作为三元组的第一个元素,之后使用双指针,left指针指向第一个元素下标+1的元素,right指针指向数组的最后一个元素。看双指针指向的元素的和 + 第一个元素之后和0的关系,如果三者的和比0小,(暂时固定第一个元素,寻找第二个和第三个元素),left++,比0大,right--。

因为要求答案中不能出现重复的三元组,所以记得去重。

python 

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        # 预判
        n = len(nums)
        if n < 3:return []
        nums.sort() # 排序之后数组才有规律,才有意义
        # 初始化
        ans = list()
        for i in range(n):
            if nums[i] > 0:return ans
            if i > 0 and nums[i] == nums[i-1]:continue # 去重
            # 双指针
            left ,right = i+1,n-1
            while left < right:
                if left < right and nums[left] + nums[right] < -nums[i]:left += 1
                elif left < right and nums[left] + nums[right] > -nums[i]: right -= 1
                else:
                    ans.append([nums[i],nums[left],nums[right]])
                    left += 1
                    right -= 1
                    # 去重
                    while left < right and nums[left] == nums[left-1]:left += 1
                    while left < right and nums[right] == nums[right+1]: right -= 1
        return ans

c++ 

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        //排序 + 双指针
        int n = nums.size();
        if (n < 3) return {};
        sort(nums.begin(),nums.end());
        vector<vector<int>> ans;
        for (int i = 0;i < n;i++){
            if (nums[i] > 0) return ans;
            if (i > 0 && nums[i] == nums[i-1]) continue;
            int left = i+1,right = n-1;
            while (left < right){
                if (nums[left] + nums[right] < -nums[i]) left++;
                else if (nums[left] + nums[right] > -nums[i]) right--;
                else{
                    ans.push_back(vector<int>{nums[i],nums[left],nums[right]});
                    left++;
                    right--;
                    while (left < right && nums[left] == nums[left-1]) left++;
                    while (left < right && nums[right] == nums[right+1]) right--;
                }
            }
        }
        return ans;

    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值