摩尔投票算法和双指针进阶

文章讲述了如何使用贪心和双指针策略解决LeetCode中的两个问题:11.盛最多水的容器,通过调整左右指针位置找到容器能容纳的最大水量;169.多数元素,利用摩尔投票算法快速找出出现次数超过半数的元素。作者分享了解题过程和关键思路。
摘要由CSDN通过智能技术生成

  好久没写这个了,刷不动二叉树力,但是看到几个比较有意思的题目,直接细嗦。

1.leetcode11. 盛最多水的容器

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

返回容器可以储存的最大水量。

说明:你不能倾斜容器。

输入:[1,8,6,2,5,4,8,3,7]
输出:49 
解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。

示例 2:

输入:height = [1,1]
输出:1

提示:

  • n == height.length
  • 2 <= n <= 105
  • 0 <= height[i] <= 104

这道题目还是蛮有意思的,一开始想了一个答辩双指针方法,就是去暴力的一个个遍历,从下标1开始作为终止下标往前求最大值,再用一个变量记录最大值,后面怎么修改都还是超时了,一开始我还以为我这个方法是动态规划,后面发现我这就是一个答辩纯暴力,后面看了题解才知道这是一道贪心加双指针的问题

class Solution {
public:
    int maxArea(vector<int>& height) {
        int left=0,right=height.size()-1;
        int maxnum=0;
        while(left!=right){
            maxnum=max(maxnum,(right-left)*min(height[left],height[right]));
            if(height[right]<height[left]){right--;}
            else{left++;}
        }
        return maxnum;
    }
};

这里我们分别设置两个指针left和right分别指向height的头和尾,对于双指针的处理方式就是哪一个指针所对应的值较小,则哪个指针向中间靠近,然后求出这两个指针所围成的容器的最大值。不知道为什么感觉有点像那个滑动窗口,但是却是贪心的思想。

2.LeetCode169. 多数元素

给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

示例 1:

输入:nums = [3,2,3]
输出:3

示例 2:

输入:nums = [2,2,1,1,1,2,2]
输出:2

提示:

  • n == nums.length
  • 1 <= n <= 5 * 104
  • -109 <= nums[i] <= 109

进阶:尝试设计时间复杂度为 O(n)、空间复杂度为 O(1) 的算法解决此问题。

这道题目我一开始是想一个个暴力查找数据,后来发现了一个很奇妙的算法叫摩尔投票算法

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int temp=nums[0];
        int total=1;
        for(int i=1;i<nums.size();i++){
            if(temp==nums[i]){total++;}
            else if(--total==0){temp=nums[i+1];}
        }
        return temp;
    }
};

对于这道题目解释一下大体的思路就是随机删除两个任意两个不相同的数最后剩余的数就是我们要找的数,于是我们可以每次将第一个数设置成1,向后遍历如果与第一个数不相同则设置成-1,这些数的和如果等于0则将下一个数设置成1,最终得到的数就是要找的。

其实摩尔投票算法还有很多进阶的题目,假如是大于三分之一那么就是要找到三互不相同的数进行筛选。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值