【算法一则】贪心加双指针-盛水最多的容器

news2024/11/28 18:46:28

目录

  • 题目
  • 题解
    • 贪心算法
    • 双指针
    • 解题思路
      • 暴力破解法
      • 双指针
  • 总结

题目

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。

说明:你不能倾斜容器。

示例 1:
在这里插入图片描述

输入:[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

题解

贪心算法

贪心算法是一种常见的算法思想,用于在求解最优化问题时做出每一步的局部最优选择,从而达到全局最优的目标。贪心算法的基本思路是,在每一步都做出当前情况下的最优选择,并希望通过这种局部最优选择的组合来达到全局最优解。

贪心算法的解题思路一般包括以下几个步骤:

  • 确定问题的最优子结构:贪心算法通常适用于具有最优子结构的问题,即问题的最优解可以通过一系列局部最优解的组合得到。

  • 定义贪心选择策略:根据问题的特点,确定每一步的最优选择是什么。这个选择应该是局部最优的,并且希望通过这个选择能够达到全局最优解。

  • 构造解的过程:通过贪心选择策略,逐步构建出问题的解。在每一步选择后,更新问题的状态,进而影响后续步骤的选择。

  • 验证解的正确性:在构造解的过程中,需要验证每一步的选择是否满足问题的约束条件。同时,需要证明通过贪心选择策略得到的解是最优解。

需要注意的是,贪心算法并不适用于所有问题,因为它只关注当前局部最优解,并没有考虑到全局的影响。在某些情况下,贪心算法可能会得到次优解或者无法得到可行解。因此,在应用贪心算法时需要仔细分析问题的特点,确保贪心选择策略能够得到正确的解。

一些经典的使用贪心算法的问题包括:

零钱兑换问题:给定一定面额的硬币,求解如何用最少的硬币数凑出给定的金额。
区间调度问题:给定一组区间,求解如何选择最多的不重叠区间。
跳跃游戏问题:给定一个非负整数数组,每个元素表示在当前位置能够跳跃的最大步数,求解是否能够到达数组的最后一个位置。

在解决这些问题时,贪心算法能够提供高效的解决方案。但对于不同的问题,贪心选择策略的选择和实现方式可能会有所不同,需要根据具体问题进行分析和设计。

双指针

双指针算法是一种常见的算法技巧,它通过使用两个指针在数组或链表中同时移动,以解决一些特定的问题。双指针算法通常用于处理有序数组或链表的问题,可以在O(n)的时间复杂度内解决一些问题,而不需要额外的空间复杂度。

双指针算法的解题思路一般包括以下几个步骤:

初始化指针:通常情况下,会初始化两个指针,一个指向数组或链表的起始位置,另一个指向末尾位置或者某个特定位置。

移动指针:根据问题的要求,移动指针的位置。可以根据当前指针指向的元素值或者某种条件来决定指针的移动方式。

判断条件:在移动指针的过程中,根据题目要求或者特定的条件,判断是否满足某种条件。

更新解或结果:根据判断条件的结果,更新解或者结果。

双指针算法常见的题型包括:

快慢指针:使用两个指针,一个快指针每次移动两步,一个慢指针每次移动一步。常用于判断链表是否存在环、找到链表的中间节点等问题。

左右指针:在有序数组中,使用两个指针分别指向数组的左右两端,根据数组的性质移动指针,以快速搜索或者判断满足条件的元素。

对撞指针:在有序数组中,使用两个指针分别从数组的两端向中间移动,根据数组的性质移动指针,以快速搜索或者判断满足条件的元素。

滑动窗口:使用两个指针构成一个窗口,在数组或字符串中滑动窗口,根据窗口的性质移动指针,以求解最优解或者满足特定条件的解。

一些经典的使用双指针算法的问题包括:

两数之和:给定一个有序数组和一个目标值,找出数组中和为目标值的两个数的索引。
反转数组:给定一个数组,将数组中的元素反转。
链表相交:给定两个链表,判断两个链表是否相交,并找到相交的节点。
最长回文子串:给定一个字符串,找到字符串中最长的回文子串。

双指针算法能够提供高效的解决方案,但需要根据具体问题进行分析和设计,选择合适的指针移动策略和判断条件。

解题思路

暴力破解法

首先拿到这个题目,第一时间想到就是暴力破解法。拿每数组中任意一个数和其他的数组成容器,暴力循环直到找到最大的那个数。
在这里插入图片描述

public int maxArea(int[] height) {
    int i = 0;
    int max = Integer.MIN_VALUE;
    while(i < height.length - 1) {
        for (int j = height.length - 1; j > i; j --) {
        	// 这里做了一点小优化,如果说最后面的那个数 height[j] >= height[i]的话就没必要继续往左边走了,因为往左边的数比height[i]大或小都没有意义了,由于木桶效应,决定木桶装水容量的应该是最小的那块木板。所以容器的容量最大应该就是两边都是高度都是height[i]。所以 height[j] >= height[i] 已经取到了左边高度为height[i]的情况下,容量最大也就是height[i] * (j - i) .
            if (height[j] >= height[i]) { // 如果没这段优化直接就会超时
                max = Math.max(height[i] * (j - i), max);
                break;
            } else {
                max = Math.max(height[j] * (j - i), max);
            }
        }
        i ++;
    }
    return max;
}

看到下图明显可以知道,性能很差,肯定不应该这样去做。
在这里插入图片描述

双指针

贪心算法的核心思想就是要求我们每一步都是最优解,从而得出全局最优。我们创建两个指针,保证left 和right在移动的时候,每一步都是最优解,从而得出全局最优。

步骤 ①
在这里插入图片描述
步骤 ②
在这里插入图片描述
步骤③
在这里插入图片描述

public int maxAreaTwoPoint(int[] height) {
    int i = 0, j = height.length - 1;
    int max = Integer.MIN_VALUE;
    while (i < j) {
        if (height[i] < height[j]) {
            max = Math.max(height[i] * (j - i), max);
            i ++;
        } else {
            max = Math.max(height[j] * (j - i), max);
            j --;
        }
    }
    return max;
}

总结

贪心算法是一种常用的优化算法思想,它通过每一步选择当前最优解的策略,以期望达到全局最优解。贪心算法具有以下特点:贪心选择性质和局部最优解。贪心算法的步骤包括确定最优子结构、构建贪心选择、定义最优解的边界和迭代执行贪心选择。然而,贪心算法并不适用于所有问题,只适用于具备贪心选择性质的问题。在使用贪心算法时,需要仔细分析问题的特点,确保贪心选择的正确性,并进行适当的证明。贪心算法是一种简单而高效的算法思想,常用于解决优化问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1581765.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

设计模式学习笔记 - 设计模式与范式 -行为型:7.责任链模式(下):框架中常用的过滤器、拦截器是如何实现的?

概述 上篇文章《6.责任链模式&#xff08;上&#xff09;&#xff1a;原理与实现》&#xff0c;学习了职责链模式的原理与实现&#xff0c;并且通过一个敏感词过滤框架的例子&#xff0c;展示了职责链模式的设计意图。本质上来说&#xff0c;它跟大部分设计模式一样&#xff0…

不到6毛钱的I2C总线实时时钟日历芯片LK8563

前言 8563实时时钟芯片&#xff0c;国内外均有多家生产&#xff0c;今推荐一个性价比极高的RTC芯片&#xff0c;LK8563&#xff0c;一片不到6毛钱. 特点 基于32.768kHz晶体的秒&#xff0c;分&#xff0c;小时&#xff0c;星期&#xff0c;天&#xff0c;月和年的计时 带有世…

【堡垒机】堡垒机的介绍

目前&#xff0c;常用的堡垒机有收费和开源两类。 收费的有行云管家、纽盾堡垒机&#xff1b; 开源的有jumpserver&#xff1b; 这几种各有各的优缺点&#xff0c;如何选择&#xff0c;大家可以根据实际场景来判断 什么是堡垒机 堡垒机&#xff0c;即在一个特定的网络环境下&…

第十届蓝桥杯大赛个人赛省赛(软件类) CC++ 研究生组-RSA解密

先把p&#xff0c;q求出来 #include<iostream> #include<cmath> using namespace std; typedef long long ll; int main(){ll n 1001733993063167141LL, sqr sqrt(n);for(ll i 2; i < sqr; i){if(n % i 0){printf("%lld ", i);if(i * i ! n) pri…

Matlab|【防骗贴】【免费】基于主从博弈的主动配电网阻塞管理

目录 1 主要内容 程序亮点 2 部分代码 3 程序结果 4 下载链接 1 主要内容 《基于主从博弈的主动配电网阻塞管理》文献介绍&#xff1a;主要采用一种配电网节点边际电价统一出清的主从博弈双层调度框架。上层框架解决用户在负荷聚合商引导下的用电成本最小化问题&#xff0…

电脑更新到win11后不能上网,更新win11后无法上网

越来越多的用户升级了win11系统使用&#xff0c;然而有些用户发现电脑更新到win11后不能上网了&#xff0c;这是怎么回事呢?而且奇怪的是&#xff0c;网络状态显示已连接&#xff0c;但就是无法上网&#xff0c;原本以为重置网络就能搞定&#xff0c;但结果相反。针对这一情况…

DRF的认证、权限、限流、序列化、反序列化

DRF的认证、权限、限流、序列化、反序列化 一、认证1、直接用&#xff0c;用户授权2、认证组件源码 二、权限1. 直接使用&#xff0c;用户权限2.权限组件源码 三、序列化1. 序列化1.1 自定义Serailizer类序列化1.2 在视图APIView中使用1.3 自定义ModelSerializer类序列化1.4 不…

vue3 +Taro 页面实现scroll-view 分页功能

需求 现在分页列表 后端只给你一个分页的数据列表 没有总页数 没有当前的分页 页数 只有这么一个list 、、、 如何去分页 我这使用的是scroll-view 组件 滑动到底部的事件 根据你当前设定的每页的数据数量和后端返回给你的数据列表数量 当某一次分页 两个数量不相等了以后 就…

ActiveMQ介绍及linux下安装ActiveMQ

ActiveMQ介绍 概述 ActiveMQ是Apache软件基金下的一个开源软件&#xff0c;它遵循JMS1.1规范&#xff08;Java Message Service&#xff09;&#xff0c;是消息队列服务&#xff0c;是面向消息中间件&#xff08;MOM&#xff09;的最终实现&#xff0c;它为企业消息传递提供高…

目标检测——YOLO系列学习(一)YOLOv1

YOLO可以说是单阶段的目标检测方法的集大成之作&#xff0c;必学的经典论文&#xff0c;从准备面试的角度来学习一下yolo系列。 YOLOv1 1.RCNN系列回顾 RCNN系列&#xff0c;无论哪种算法&#xff0c;核心思路都是Region Proposal&#xff08;定位&#xff09; classifier&am…

DJI无人机二次开发:模拟航线飞行

1.下载大疆行业调参软件&#xff08;大疆官网下载&#xff0c;有mac系统和win系统&#xff09;。 2.安装软件以后用数据线连接电脑和无人机 3.识别无人机点击进去进入模拟器设置和遥控器相同的经纬坐标 4.在遥控器上载入航线 5.开始执行以后在上云api可以看到无人机在地图上移动…

目标检测——3D车道数据集

一、重要性及意义 3D车道检测在自动驾驶和智能交通领域具有极其重要的地位&#xff0c;其重要性和意义主要体现在以下几个方面&#xff1a; 首先&#xff0c;3D车道检测可以精确判断车辆在道路上的位置、方向和速度&#xff0c;从而预测潜在的危险情况并及时采取措施。这种能…

数据结构速成--数据结构和算法

由于是速成专题&#xff0c;因此内容不会十分全面&#xff0c;只会涵盖考试重点&#xff0c;各学校课程要求不同 &#xff0c;大家可以按照考纲复习&#xff0c;不全面的内容&#xff0c;可以看一下小编主页数据结构初阶的内容&#xff0c;找到对应专题详细学习一下。 目录 一…

pdffactory pro 8注册码序列号下载 附教程

PdfFactory Pro可以说是一款行业专业且技术领先的的PDF虚拟打印机软件。其不仅占用系统内存小巧&#xff0c;功能强大&#xff0c;可支持用户无需使用Acrobat来创建Adobe PDF即可以进行PDF组件的创建和打印。同时&#xff0c;现在全新的PdfFactory Pro 8也正式上线来袭&#xf…

【资源分享】MAC上最好用的截图软件-Snipaste

::: block-1 “时问桫椤“是一个关注本科生到研究生教育阶段的不严肃的公众号&#xff0c;希望能在大家迷茫、难受、困难之时帮助到大家。用广大研究生的经验总结&#xff0c;让大家能尽早的适应研究生生活&#xff0c;尽快的看透科研本质。祝好&#xff01;&#xff01;&#…

Day94:云上攻防-云服务篇弹性计算云数据库实例元数据控制角色AK控制台接管

目录 云服务-弹性计算服务器-元数据&SSRF&AK 前提条件 利用环境1&#xff1a;获取某服务器权限后横向移动 利用环境2&#xff1a;某服务器上Web资产存在SSRF漏洞 云服务-云数据库-外部连接&权限提升 云上攻防-如何利用SSRF直接打穿云上内网 知识点&#xff1…

科技动态人工智能应用太空探索生物科技

根据最新的科技资讯&#xff0c;以下是一些值得关注的科技动态&#xff1a; 人工智能领域 智能体热潮 &#xff1a;随着大模型的研发热潮&#xff0c;AI智能体的发展迅速&#xff0c;它们被用作认知核心&#xff0c;具备强大的学习和迁移能力。智能体的架构和交互方式也在不断进…

vue快速入门(十五)监听键盘事件

注释很详细&#xff0c;直接上代码 上一篇 新增内容 特定按键监听事件全按键监听事件及两种判断方法 源码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthde…

03-JAVA设计模式-代理模式详解

代理模式 什么是代理模式 Java代理模式是一种常用的设计模式&#xff0c;主要用于在不修改现有类代码的情况下&#xff0c;为该类添加一些新的功能或行为。代理模式涉及到一个代理类和一个被代理类&#xff08;也称为目标对象&#xff09;。代理类负责控制对目标对象的访问&a…

蓝桥杯简单STL

目录 vector vector定义 vector访问 常用函数 size() ​编辑 push_back(num) pop_back() clear 迭代器&#xff08;iterator) 迭代器定义 遍历数组示例 insert(it, element) erase(it) 标准模板库--STL&#xff0c;它包含了多种预定义的容器、算法和迭代器&…