@Author:Runsen

@Date:2020/7/5

人生最重要的不是所站的位置,而是内心所朝的方向。只要我在每篇博文中写得自己体会,修炼身心;在每天的不断重复学习中,耐住寂寞,练就真功,不畏艰难,奋勇前行,不忘初心,砥砺前行,人生定会有所收获,不留遗憾 (作者:Runsen )

作者介绍:Runsen目前大三下学期,专业化学工程与工艺,大学沉迷日语,Python, Java和一系列数据分析软件。导致翘课严重,专业排名中下。.在大学60%的时间,都在CSDN。决定今天比昨天要更加努力。前面文章,点击下面链接

我的Python教程,不断整理,反复学习

今日,我决定继续更新Python教程,今天就开始了八十三、Python | Leetcode贪心算法系列。

贪心算法

贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。

假设我们有一个100kg的背包,可以装飞中物品,如何将所装的物品总价值最大


答案 :20kg 黑豆 ,30kg 绿豆 ,50kg 红豆

贪心算法的基本思路是从问题的某一个初始解出发一步一步地进行,根据某个优化测度,每一步都要确保能获得局部最优解。每一步只考虑一个数据,他的选取应该满足局部优化的条件。若下一个数据和部分最优解连在一起不再是可行解时,就不把该数据添加到部分解中,直到把所有数据枚举完,或者不能再添加算法停止

贪心算法的解题步骤

  • 建立数学模型来描述问题;
  • 把求解的问题分成若干个子问题;
  • 对每一子问题求解,得到子问题的局部最优解;
  • 把子问题的解局部最优解合成原来解问题的一个解。

在比如,有一个有权图,从顶点S开始,照样一条到顶点T的最短路径

贪心算法的解决思路

每次选择一条跟当前相连的权最小的边,直到找出顶点T。

求出的最短路径S ->A->E->T,路径长度1+4+4 =9但是贪心选择的方法,求的路径并不是最短路径  S- >B ->D->T 才是最短路径

因为前面的选择会影响后面的选择,导致每一步的选择都很糟糕,最终无法得到全局最优解

生活中常见的贪心算法就是钱币付钱

肯定先用最大的100来付钱,如果不够,就用50,最后剩下的用1元来补齐

1.贪婪算法可以寻找局部最优解,并尝试与这种方式获得全局最优解

2.得到的可能是近似最优解,但也可能便是最优解(区间调度问题,最短路径问题(广度优先、狄克斯特拉))

3.对于完全NP问题,目前并没有快速得到最优解的解决方案

4.面临NP完全问题,最佳的做法就是使用近似算法

5.贪婪算法(近似算法)在大部分情况下易于实现,并且效率不错

举个简单的例子,比如给定某个数字的金额(如 250)与 100, 50, 10, 5, 1 这些纸币(不限量),怎么能用最少张的纸币来兑换这张金额呢,显然每次兑换应该先从大额的纸币兑换起,第一次选 100, 第二次还是选 100, 第三次选第二大的 50 元,每次都选小于剩余金额中的最大面额的纸币,这样得出的解一定是全局最优解!时间复杂度无疑是线性的。

最大和的连续子数组

我不知道这题是不是Leetcode,但出现的频率很高。好像是牛课的,反正是一个面试题。

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。示例:输入: [-2,1,-3,4,-1,2,1,-5,4],输出: 6解释: 连续子数组[4,-1,2,1] 的和最大,为 6。

第一时间想到的当然是暴力解决,基本思路就是遍历一遍,用两个变量,一个记录最大的和,一个记录当前的和。后面发现可以用贪心算法来解比较简单其基本思路是正在访问的节点值+此节点之前的最大值如果大于当前节点,则更新最大值为和,否则更新最大值为当前节点。

nums=[-2,1,-3,4,-1,2,1,-5,4]tmp = nums[0]max_ = tmpn = len(nums)for i in range(1,n):    # 当当前序列加上此时的元素的值大于tmp的值,说明最大序列和可能出现在后续序列中,记录此时的最大值if tmp + nums[i]>nums[i]:       max_ = max(max_, tmp+nums[i])       tmp = tmp + nums[i]   else:       #当tmp(当前和)小于下一个元素时,当前最长序列到此为止。以该元素为起点继续找最大子序列,        # 并记录此时的最大值       max_ = max(max_, tmp, tmp+nums[i],  nums[i])       tmp = nums[i]print(max_)

贪心算法的代码

nums=[-2,1,-3,4,-1,2,1,-5,4]lenth = len(nums)cur_sum=max_sum = nums[0]for i in range(1,lenth): cur_sum = max(cur_sum+nums[i],  nums[i]) max_sum = max(cur_sum, max_sum)print(max_sum)

我们再看一个场景,这是一个求得最优解的贪心算法例子。

场景:一名收银员,需要找零 88元。怎么找零,所需要的纸/硬币的数量最少。

思路:依次找最大的纸币, 例如:找零88元, ¥88 = ¥50 + ¥20 + ¥10 + ¥5 + ¥1 * 3

# arr的每一位:分别对应100块、50块、20块、10块、5块、1块纸币。arr = [0,0,0,0,0,0]

def change(money):while money >= 1:        if money >= 100:            money -= 100            arr[0] += 1        elif money >= 50:            money -= 50            arr[1] += 1        elif money >= 20:            money -= 20            arr[2] += 1        elif money >= 10:            money -= 10            arr[3] += 1        elif money >= 5:            money -= 5            arr[4] += 1        elif money >= 1:            money -= 1            arr[5] += 1

change(88)print(arr)

LeetCode 第 55题:跳跃游戏

#给定一个非负整数数组,你最初位于数组的第一个位置。 # 数组中的每个元素代表你在该位置可以跳跃的最大长度。 # 判断你是否能够到达最后一个位置。 # 示例 1:# 输入: [2,3,1,1,4]#输出: true#解释: 我们可以先跳 1 步,从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。# 示例 2: # 输入: [3,2,1,0,4]#输出: false#解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 , 所以你永远不可能到达最后一个位置。# Related Topics 贪心算法 数组

从第i个位置,最远可跳nums[i]步:nums=[2,3,1,1,4,...];我们假设从第i个位置,最远可跳至第index[i]个位置,则index[i] = i + nums[i];

若从第0个位置最远可跳至第i个位置;则从第0个位置也一定可以跳至:第1个位置、第2个位置、...、第i-1个位置。从第0个位置,应该跳至第1、第2、...、第i-1个位置中的哪一个呢?

应该调至第1、2、...、i-1、i位置中,又可向前跳至最远位置(即index[1]、index[2]、...、index[i-1] 和 index[i] 最大的那个)(贪心算法的思想)

算法步骤:

  • 求从第i个位置最远可跳至第index[i]位置;

  • 根据从第i位置最远可跳nums[i]步:index[i] = nums[i] + i;

  • 初始化:设置变量i代表当前所处的位置,初始化为0;设置变量max_index代表从第0位置至第i位置的这个过程中,最远可到达的位置,初始化为index[0]。

  • 利用i扫描index数组,直到i到达index数组尾部或i超过max_index,扫描过程中,更新max_index.

  • 若最终 i 为数组长度,则返回true,否则返回false。

class Solution:    def canJump(self, nums: List[int]) -> bool:        farthest = nums[0]        for i in range(len(nums)):if i <= farthest:                farthest = max(i+nums[i], farthest)        return len(nums)-1 <= farthest

LeetCode 第 122题:买卖股票的最佳时机 II

#给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。 # 设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。 # 注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。 # 示例 1: # 输入: [7,1,5,3,6,4]#输出: 7#解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。#     随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。# 示例 2: # 输入: [1,2,3,4,5]#输出: 4#解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。#     注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。#     因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。# 示例 3: # 输入: [7,6,4,3,1]#输出: 0#解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。 # 提示: # 1 <= prices.length <= 3 * 10 ^ 4 # 0 <= prices[i] <= 10 ^ 4 # Related Topics 贪心算法 数组

虽然题目看似复杂, 但真正完成的时候你会发现这道题是纸老虎。于是题目的思路就是遍历整个数组, 预测 i+1 个交易日比 i 高即可卖出, 累加利润; 否则跳过这个交易日. 什么?你觉得不可能这么简单? 事实就是这么简单!

class Solution:    def maxProfit(self, prices: List[int]) -> int:        # return sum([max(prices[i+1] - prices[i],0) for i in range(len(prices)-1)])        return sum([prices[i+1]-prices[i] if prices[i+1]-prices[i] > 0 else 0 for i in range(len(prices)-1)])        # return sum([y - x for x, y in zip(prices[:-1], prices[1:]) if x y])

python leetcode_八十二、Python | Leetcode贪心算法系列相关推荐

  1. 八十二、Python | Leetcode贪心算法系列

    @Author:Runsen @Date:2020/7/5 人生最重要的不是所站的位置,而是内心所朝的方向.只要我在每篇博文中写得自己体会,修炼身心:在每天的不断重复学习中,耐住寂寞,练就真功,不畏艰 ...

  2. [Python图像处理] 四十二.Python图像锐化及边缘检测万字详解(Roberts、Prewitt、Sobel、Laplacian、Canny、LOG)

    该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门.OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子.图像增强技术.图像分割等,后期结合深度学习研究图像识别 ...

  3. 八十四、Python | Leetcode回溯算法系列

    @Author:Runsen @Date:2020/7/7 人生最重要的不是所站的位置,而是内心所朝的方向.只要我在每篇博文中写得自己体会,修炼身心:在每天的不断重复学习中,耐住寂寞,练就真功,不畏艰 ...

  4. 孤荷凌寒自学python第八十五天配置selenium并进行模拟浏览器操作1

    孤荷凌寒自学python第八十五天配置selenium并进行模拟浏览器操作1 (完整学习过程屏幕记录视频地址在文末) 要模拟进行浏览器操作,只用requests是不行的,因此今天了解到有专门的解决方案 ...

  5. python二级第十二套答案

    python二级第十二套答案 46.考生文件夹下存在三个Python源文件,分别对应三个问题,请按照文件内说明修改代码,实现以下功能: 法定节假日是根据各国.各名族的风俗习惯或纪念要求,由国家法律统一 ...

  6. python图像处理笔记-十二-图像聚类

    python图像处理笔记-十二-图像聚类 学习内容 这一章主要在学习的是聚类算法以及其在图像算法中的应用,主要学习的聚类方法有: KMeans 层次聚类 谱聚类 并将使用他们对字母数据及进行聚类处理, ...

  7. 孤荷凌寒自学python第三十九天python 的线程锁Lock

    孤荷凌寒自学python第三十九天python的线程锁Lock (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 当多个线程同时操作一个文件等需要同时操作某一对象的情况发生时,很有可能发生冲突, ...

  8. Python 线程池 ThreadPoolExecutor(二) - Python零基础入门教程

    目录 一.Python 线程池前言 二.Python 线程池 ThreadPoolExecutor 常用函数 1.线程池 as_completed 函数使用 2.线程池 map 函数使用 3.线程池 ...

  9. JavaScript学习(八十二)—JavaScript的组成

    JavaScript学习(八十二)-JavaScript的组成 一.ECMAScript ECMAScript是由ECMA国际(原欧洲计算机制造商协会)进行标准化的一门编程语言,这种语言在万维网上应用 ...

最新文章

  1. 剪切工具怎么用_原创度检测工具是怎么用的?优质的内容更容易获得平台推荐...
  2. Android Studio获得sha1码
  3. SparkSQL之DataFrame案例
  4. 【小题目】写JAVA程序时可以创建一个名为123.java的源文件吗
  5. jquery.form.js java_教javascript函数和jquery函数的使用$(form).submit(function()
  6. 以太网CSMA/CD算法交换机自学习/转发简述
  7. CRLF对GIT DIFF的影响
  8. tld自定义标签之基础入门篇
  9. OpenCV 网络视频传输 C++ 和 python实现
  10. 马哥linux视频笔记,马哥linux培训第四天笔记
  11. 最近在上海浦东新区的租房经历
  12. win10基于QT开发手机安卓App
  13. 一条sql语句查出男生前5名和女生前五名
  14. 迁移学习---TrAdaBoost算法介绍
  15. 构建ceph可视化监控(prometheu+grafana)
  16. maya藤蔓插件_3DMax藤蔓生长插件Guruware Ivy For 3dsmax中英文版本
  17. WEB综合案例 黑马面面 day04 用户与角色绑定功能 登录用户菜单控制和权限效验
  18. 物联网环境下的隐私保,需要从哪几方面考虑
  19. 通过修改注册表激活 Windows 操作系统
  20. To_Heart—题解——令人窒息的操作

热门文章

  1. 2017.7.8 MS SQL Server and BI workshop
  2. iOS多线程: pthread、NSThread
  3. ssh登录到esxi机器中后开关虚拟机
  4. PL/SQL Developer远程连接Oracle数据库
  5. 修改MYSQL数据库表的字符集
  6. MYSQL命令行常用命令
  7. 华为机试HJ28:素数伴侣
  8. mysql集群集成springboot_springboot配置数据库包括集群下 配置
  9. 测试用例的优先级概念
  10. android中获取应用程序(包)的信息,Android中获取应用程序(包)的信息PackageManager的使用(一).doc...