【leetcode刷题之路】面试经典150题(7)——分治+Kadane 算法+二分查找+堆

文章目录

      • 16 分治
        • 16.1 【分治】将有序数组转换为二叉搜索树
        • 16.2 【归并排序】排序链表
        • 16.3 【分治】建立四叉树
        • 16.4 【暴力】合并 K 个升序链表
      • 17 Kadane 算法
        • 17.1 【动态规划】最大子数组和
        • 17.2 【动态规划】环形子数组的最大和
      • 18 二分查找
        • 18.1 【二分】搜索插入位置
        • 18.2 【二分】搜索二维矩阵
        • 18.3 【二分】寻找峰值
        • 18.4 【二分】搜索旋转排序数组
        • 18.5 【二分】在排序数组中查找元素的第一个和最后一个位置
        • 18.6 【二分】寻找旋转排序数组中的最小值
        • 18.7 【二分】寻找两个正序数组的中位数
      • 19 堆
        • 19.1 【二分】数组中的第K个最大元素
        • 19.2 【贪心】502. IPO
        • 19.3 【优先队列】查找和最小的 K 对数字

16 分治

16.1 【分治】将有序数组转换为二叉搜索树

题目地址:https://leetcode.cn/problems/convert-sorted-array-to-binary-search-tree/description/?envType=study-plan-v2&envId=top-interview-150

  详见代码。

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = rightclass Solution:def sortedArrayToBST(self, nums: List[int]) -> Optional[TreeNode]:def divide(nums,left,right):if left > right:return Noneelse:m = (left+right)//2root = TreeNode(nums[m])root.left = divide(nums,left,m-1)root.right = divide(nums,m+1,right)return rootreturn divide(nums,0,len(nums)-1)
16.2 【归并排序】排序链表

题目地址:https://leetcode.cn/problems/sort-list/description/?envType=study-plan-v2&envId=top-interview-150

  首先找到链表的中间位置,然后使用归并排序以此递归遍历链表。

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = nextclass Solution:def sortList(self, head: Optional[ListNode]) -> Optional[ListNode]:if not head or not head.next:return headslow,fast = head,head.nextwhile fast and fast.next:slow,fast = slow.next,fast.next.nextmid = slow.nextslow.next = Noneleft,right = self.sortList(head),self.sortList(mid)h = ans = ListNode()while left and right:if left.val < right.val:h.next = leftleft = left.nextelse:h.next = rightright = right.nexth = h.nexth.next = left if left else rightreturn ans.next
16.3 【分治】建立四叉树

题目地址:https://leetcode.cn/problems/construct-quad-tree/description/?envType=study-plan-v2&envId=top-interview-150

  首先需要判断每个方块中的数字是否是相同的,其次要找到递归的条件,这里的条件就是每个方块的四个组成部分,然后以此向内遍历,直到出现叶子结点就算结束。

"""
# Definition for a QuadTree node.
class Node:def __init__(self, val, isLeaf, topLeft, topRight, bottomLeft, bottomRight):self.val = valself.isLeaf = isLeafself.topLeft = topLeftself.topRight = topRightself.bottomLeft = bottomLeftself.bottomRight = bottomRight
"""class Solution:def construct(self, grid: List[List[int]]) -> 'Node':# if current grid is leaf or notdef is_grid(grid):l = len(grid)ssum = 0for i in range(l):ssum += sum(grid[i])if ssum == l*l:return Trueelif ssum == 0:return Falseelse:return Nonegrid_flag = is_grid(grid)l = len(grid)if grid_flag == True:node = Node(True,True,None,None,None,None)elif grid_flag == False:node = Node(False,True,None,None,None,None)else:m = l // 2topleft_grid = [[grid[i][j] for j in range(m)] for i in range(m)]topright_grid = [[grid[i][j] for j in range(m,l)] for i in range(m)]bottomleft_grid = [[grid[i][j] for j in range(m)] for i in range(m,l)]bottomright_grid = [[grid[i][j] for j in range(m,l)] for i in range(m,l)]node = Node(False,False,self.construct(topleft_grid),self.construct(topright_grid),self.construct(bottomleft_grid),self.construct(bottomright_grid))return node
16.4 【暴力】合并 K 个升序链表

题目地址:https://leetcode.cn/problems/merge-k-sorted-lists/description/?envType=study-plan-v2&envId=top-interview-150

  将链表两两合并。

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = nextclass Solution:def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]:def merge(l1,l2):cur = tmp = ListNode()while l1 and l2:if l1.val < l2.val:tmp.next = l1l1 = l1.nextelse:tmp.next = l2l2 = l2.nexttmp = tmp.nextif l1:tmp.next = l1if l2:tmp.next = l2return cur.nextans = Nonefor i in lists:ans = merge(ans,i)return ans

17 Kadane 算法

17.1 【动态规划】最大子数组和

题目地址:https://leetcode.cn/problems/maximum-subarray/description/?envType=study-plan-v2&envId=top-interview-150

  利用动态规划,首先定义数组 d p [ i ] dp[i] dp[i],表示终点下标为i的序列的最大子数组和,主要考虑以下两种情况:

  • 如果 d p [ i − 1 ] dp[i-1] dp[i1]大于 0 0 0,则继续向前增加下标为i的数值,作为 d p [ i ] dp[i] dp[i]的子数组和;
  • 如果 d p [ i − 1 ] dp[i-1] dp[i1]小于 0 0 0,则从这里开始停止,重新计算子数组和,赋值为 0 0 0后再加入下标为i的数值,作为 d p [ i ] dp[i] dp[i]的子数组和。

  最后的结果就是数组中最大的那个值。

class Solution:def maxSubArray(self, nums: List[int]) -> int:ans,dp = nums[0],nums[0]for i in range(1,len(nums)):dp = max(dp,0) + nums[i]if dp > ans:ans = dpreturn ans
17.2 【动态规划】环形子数组的最大和

题目地址:https://leetcode.cn/problems/maximum-sum-circular-subarray/description/?envType=study-plan-v2&envId=top-interview-150

  分为两种情况,如果答案在数组中间,则是最大子数组和,如果答案在数组两边,则是数字的和减去最小子数组和。

class Solution:def maxSubarraySumCircular(self, nums: List[int]) -> int:ans_max,dp_max = nums[0],nums[0]ans_min,dp_min = nums[0],nums[0]total = sum(nums)for i in range(1,len(nums)):dp_max = max(dp_max,0) + nums[i]if dp_max > ans_max:ans_max = dp_maxdp_min = min(dp_min,0) + nums[i]if dp_min < ans_min:ans_min = dp_minif total - ans_min == 0:return ans_maxelse:return max(ans_max,total-ans_min)

18 二分查找

18.1 【二分】搜索插入位置

题目地址:https://leetcode.cn/problems/search-insert-position/description/?envType=study-plan-v2&envId=top-interview-150

  二分查找,注意左右边界的取值。

class Solution:def searchInsert(self, nums: List[int], target: int) -> int:left,right = 0,len(nums)-1while left <= right:m = (left+right)//2if target < nums[m]:right = m-1elif target > nums[m]:left = m+1else:return mreturn right+1
18.2 【二分】搜索二维矩阵

题目地址:https://leetcode.cn/problems/search-a-2d-matrix/?envType=study-plan-v2&envId=top-interview-150

  双二分查找。

class Solution:def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:row,col = len(matrix),len(matrix[0])row_l,row_r = 0,row-1while row_l <= row_r:m = (row_l+row_r)//2if target < matrix[m][0]:row_r = m-1elif target > matrix[m][0]:row_l = m+1elif target == matrix[m][0]:return Trueif row_r == 0 and matrix[row_r][0] > target:return Falsecol_l,col_r = 0,col-1while col_l <= col_r:m = (col_l+col_r)//2if target < matrix[row_r][m]:col_r = m-1elif target > matrix[row_r][m]:col_l = m+1elif target == matrix[row_r][m]:return Truereturn False
18.3 【二分】寻找峰值

题目地址:https://leetcode.cn/problems/find-peak-element/description/?envType=study-plan-v2&envId=top-interview-150

  如果中间位置的值比左边大,那么在该索引的右边一定存在峰值;同理,如果中间位置的值比右边大,那么在该索引的左边一定存在峰值,最后注意中间索引的取值,避免出现循环。

class Solution:def findPeakElement(self, nums: List[int]) -> int:l,r = 0,len(nums)-1while l < r:m = (l+r+1)//2if nums[m] > nums[m-1]:l = melse:r = m-1return l
18.4 【二分】搜索旋转排序数组

题目地址:https://leetcode.cn/problems/search-in-rotated-sorted-array/description/?envType=study-plan-v2&envId=top-interview-150

  不管怎么进行旋转,数组都会被分为有序的两部分,每次进行二分前比较一下中间索引与左右边界的值,如果 n u m s [ m ] > = n u m s [ l e f t ] nums[m]>=nums[left] nums[m]>=nums[left],则索引左边有序,否则右边有序。

class Solution:def search(self, nums: List[int], target: int) -> int:left,right = 0,len(nums)-1while left <= right:m = (left+right+1)//2if nums[m] == target:return mif nums[m] >= nums[left]:if nums[left] <= target < nums[m]:right = m-1else:left = m+1else:if nums[m] < target <= nums[right]:left = m+1else:right = m-1return -1
18.5 【二分】在排序数组中查找元素的第一个和最后一个位置

题目地址:https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array/description/?envType=study-plan-v2&envId=top-interview-150

  两次二分,第一次找出第一个位置,第二次找到 t a r g e t + 1 target+1 target+1的第一个位置,该位置左边就是 t a r g e t target target最后一个位置。

class Solution:def searchRange(self, nums: List[int], target: int) -> List[int]:def bin_sort(left,right,tgt):while left <= right:m = (left+right+1)//2if nums[m] < tgt:left = m+1else:right = m-1return leftfirst = bin_sort(0,len(nums)-1,target)if first == len(nums) or nums[first]!=target:return [-1,-1]else:last = bin_sort(0,len(nums)-1,target+1) - 1return [first,last]
18.6 【二分】寻找旋转排序数组中的最小值

题目地址:https://leetcode.cn/problems/find-minimum-in-rotated-sorted-array/description/?envType=study-plan-v2&envId=top-interview-150

  详见代码。

class Solution:def findMin(self, nums: List[int]) -> int:left,right = 0,len(nums)-1while left <= right:m = (left+right+1)//2if nums[m] < nums[0]:right = m-1else:left = m+1if left == len(nums):return nums[0]else:return nums[left]
18.7 【二分】寻找两个正序数组的中位数

题目地址:https://leetcode.cn/problems/median-of-two-sorted-arrays/description/?envType=study-plan-v2&envId=top-interview-150

  如果数组的总长度是奇数,那么中位数就是第 m + n + 1 2 \frac{m+n+1}{2} 2m+n+1小的元素;如果数组的总长度是偶数,那么中位数就是第 m + n + 1 2 \frac{m+n+1}{2} 2m+n+1和第 m + n + 2 2 \frac{m+n+2}{2} 2m+n+2小的元素的平均值。

  函数get_k_min是一个辅助函数,它用于找到两个已排序数组的第 k k k小的数。它通过比较两个数组的第 k / 2 k/2 k/2个元素来实现这个功能。如果数组 1 1 1的第 k / 2 k/2 k/2个元素小于数组 2 2 2的第 k / 2 k/2 k/2个元素,那么数组 1 1 1的前 k / 2 k/2 k/2个元素一定不会是第 k k k小的数,所以可以将它们排除在外。反之亦然。这个过程会一直持续到 k k k等于 1 1 1或者其中一个数组为空。

class Solution:def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:def k_min(start1,end1,start2,end2,k):cur_nums1 = end1-start1+1cur_nums2 = end2-start2+1if cur_nums1 == 0:return nums2[start2+k-1]if cur_nums2 == 0:return nums1[start1+k-1]if k == 1:return min(nums1[start1],nums2[start2])m1 = start1 + min(cur_nums1,k//2) - 1m2 = start2 + min(cur_nums2,k//2) - 1if nums1[m1] <= nums2[m2]:return k_min(m1+1,end1,start2,end2,k-(m1-start1+1))else:return k_min(start1,end1,m2+1,end2,k-(m2-start2+1))m,n = len(nums1),len(nums2)a,b = (m+n+1)//2,(m+n+2)//2x = k_min(0,m-1,0,n-1,a)y = k_min(0,m-1,0,n-1,b)return (x+y)/2

19 堆

19.1 【二分】数组中的第K个最大元素

题目地址:https://leetcode.cn/problems/kth-largest-element-in-an-array/description/?envType=study-plan-v2&envId=top-interview-150

  详见代码。

#方法一
class Solution:def findKthLargest(self, nums: List[int], k: int) -> int:def quick_sort(num,k):big,equal,small = [],[],[]for n in num:if n > num[0]:big.append(n)elif n < num[0]:small.append(n)else:equal.append(n)if k <= len(big):return quick_sort(big,k)elif k > len(equal) + len(big):return quick_sort(small,k-len(equal)-len(big))else:return num[0]return quick_sort(nums,k)
#方法二
class Solution:def findKthLargest(self, nums: List[int], k: int) -> int:nums.sort()l = len(nums)return nums[l-k]
19.2 【贪心】502. IPO

题目地址:https://leetcode.cn/problems/ipo/description/?envType=study-plan-v2&envId=top-interview-150

  在当前的本金小于等于当前资本的项目中,每次都选择利益最大的那个,但要注意特殊情况,当前的本金已经不能投资任何项目时,直接结束。

class Solution:def findMaximizedCapital(self, k: int, w: int, profits: List[int], capital: List[int]) -> int:pro_cap = sorted(zip(profits,capital),key = lambda x:x[1])idx,l = 0,len(profits)cur = []while k:while idx < l and pro_cap[idx][1] <= w:heapq.heappush(cur,-pro_cap[idx][0])idx += 1if cur:w -= heapq.heappop(cur)else:breakk -= 1return w
19.3 【优先队列】查找和最小的 K 对数字

题目地址:https://leetcode.cn/problems/find-k-pairs-with-smallest-sums/description/?envType=study-plan-v2&envId=top-interview-150

  多路归并思想,每次将三元组(两数组之和,数组1下标idx1,数组2下标idx2)加入到优先队列中,以两个数组中较小长度的为数组1,较大长度的为数组2,每次将优先队列的栈顶出列(当前未被加入到答案的所有点对中的最小值),然后将下一组下标加入优先队列中。

class Solution:def kSmallestPairs(self, nums1: List[int], nums2: List[int], k: int) -> List[List[int]]:flag = Trueif len(nums1) > len(nums2):nums1,nums2 = nums2,nums1flag = Falsen1,n2 = len(nums1),len(nums2)ans,pq = [],[]for i in range(min(n1,k)):heapq.heappush(pq,(nums1[i]+nums2[0],i,0))while len(ans) < k:_,idx1,idx2 = heapq.heappop(pq)if flag:ans.append([nums1[idx1],nums2[idx2]])else:ans.append([nums2[idx2],nums1[idx1]])if idx2+1 < n2:heapq.heappush(pq,(nums1[idx1]+nums2[idx2+1],idx1,idx2+1))return ans
(nums2)ans,pq = [],[]for i in range(min(n1,k)):heapq.heappush(pq,(nums1[i]+nums2[0],i,0))while len(ans) < k:_,idx1,idx2 = heapq.heappop(pq)if flag:ans.append([nums1[idx1],nums2[idx2]])else:ans.append([nums2[idx2],nums1[idx1]])if idx2+1 < n2:heapq.heappush(pq,(nums1[idx1]+nums2[idx2+1],idx1,idx2+1))return ans

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

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

相关文章

ArkTs的资源Resource类型怎么转为string

使用ResourceManager同步转换 请参看&#xff1a;ResourceManager.getStringSync9 例子&#xff1a; try { let testStr: string this.context.resourceManager.getStringSync($r(app.string.test).id); } catch (error) { console.error(getStringSync failed, error code…

【四 (5)数据可视化之 Pyecharts常用图表及代码实现 】

目录 文章导航一、介绍[✨ 特性]二、安装Pyecharts三、主题风格四、占比类图表1、饼图2、环形图3、玫瑰图4、玫瑰图-多图5、堆叠条形图6、百分比堆叠条形图 五、比较排序类1、条形图2、雷达图3、词云图4、漏斗图 六、趋势类图表1、折线图2、堆叠折线图3、面积图4、堆叠面积图 七…

【AI】Ubuntu系统深度学习框架的神经网络图绘制

一、Graphviz 在Ubuntu上安装Graphviz&#xff0c;可以使用命令行工具apt进行安装。 安装Graphviz的步骤相对简单。打开终端&#xff0c;输入以下命令更新软件包列表&#xff1a;sudo apt update。之后&#xff0c;使用命令sudo apt install graphviz来安装Graphviz软件包。为…

MySQL语法分类 DQL(1)基础查询

//语法 select 字段列表 from 表名列表 where条件列表 group by分组字段 having 分组后的条件 order by排序 limit 分页限定为了更好的学习这里给出基本表数据用于查询操作 create table student (id int, name varchar(20), age int, sex varchar(5),address varchar(100),ma…

springboot/ssm图书管理系统Java图书馆借阅管理系统web图书借阅系统

springboot/ssm图书管理系统Java图书馆借阅管理系统web图书借阅系统 基于springboot(可改ssm)vue项目 开发语言&#xff1a;Java 框架&#xff1a;springboot/可改ssm vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服务器&#xff1a;tomcat 数据库&#…

将 OpenCV 与 Eclipse 结合使用(插件 CDT)

返回&#xff1a;OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;将OpenCV与gcc和CMake结合使用 下一篇&#xff1a;OpenCV4.9.0在windows系统下的安装 警告&#xff1a; 本教程可以包含过时的信息。 先决条件 两种方式&#xff0c;一种…

CODESYS开发教程13-长字符串处理

摘要&#xff1a;这是一篇写给新手的关于CODESYS开发环境的小白教程&#xff0c;一看就懂...... 在以前的《CODESYS开发教程7-字符串及其基本操作》教程中&#xff0c;介绍了字符串及其基本操作&#xff0c;有朋友看了以后觉得不过瘾&#xff0c;希望有一些关于字符串的更加深入…

Android Framework基础之C语言入门

C语言入门详解 一、C语言简介 C语言是一种通用的、过程式的编程语言&#xff0c;支持结构化编程、词法变量作用域和递归等功能&#xff0c;是迄今为止最为强大的编程语言之一。C语言设计提供了能轻松实现底层的访问&#xff0c;通常用于系统软件开发&#xff0c;应用程序的一…

ES系列之快照与恢复

概述 原理 ES底层核心基于lucene&#xff0c;一个分片即是一个lucene对象实例&#xff0c;ES快照(snapshot)本质是对lucene物理文件的拷贝。 增量快照的核心是比较lucene segements不可变文件信息&#xff0c;每次创建快照时会建立一个IndexCommit提交点&#xff0c;包含seg…

javaweb员工健康管理监护系统

项目演示视频 &#xff08;链接&#xff1a;https://pan.baidu.com/s/1WliYEUH4c0HVB7s0-1WDUA 提取码&#xff1a;1234 --来自百度网盘超级会员V5的分享&#xff09; 该项目所用到技术 java ssh框架 3&#xff1a;该项目的用到的开发工具&#xff1f; eclipse和idea都可以、m…

Echo框架:高性能的Golang Web框架

Echo框架&#xff1a;高性能的Golang Web框架 在Golang的Web开发领域&#xff0c;选择一个适合的框架是构建高性能和可扩展应用程序的关键。Echo是一个备受推崇的Golang Web框架&#xff0c;以其简洁高效和强大功能而广受欢迎。本文将介绍Echo框架的基本特点、使用方式及其优势…

JVM学习-垃圾回收专题

目录 1.如何判断对象可以回收 1.1引用计数法 1.2可达性分析算法 1.3五种引用 1.4拓展&#xff1a;直接内存 2.垃圾回收算法 2.1标记清除算法 2.2标记整理算法 2.3复制 3.分代垃圾回收 3.垃圾回收器 3.1串行垃圾回收器 3.2吞吐量优先垃圾回收器 3.3响应时间优先垃圾回收器…

什么是雪花算法?

雪花算法&#xff08;Snowflake Algorithm&#xff09;是一种分布式ID生成算法&#xff0c;由Twitter公司开发并开源。它主要用于在分布式系统中生成全局唯一、趋势递增的ID。 雪花算法生成的ID是一个64位的长整数&#xff0c;该数字被划分为几部分&#xff1a; 符号位&#xf…

Qt 实现 Asterix 报文解析库

【写在前面】 最近工作中需要解析 Cat 21 和 Cat 62 的 ADS-B 数据 ( 自己的工作包含航空领域 )。 然后&#xff0c;因为整个 Asterix 协议类别非常之多&#xff0c;每个类别的版本也多&#xff0c;纯手工实现每个版本解析根本不现实 ( 然鹅公司之前的解析库就是这么做的且做的…

win10 + cpu + pycharm + mindspore

MindSpore是华为公司自研的最佳匹配昇腾AI处理器算力的全场景深度学习框架。 1、打开官网&#xff1a; MindSpore官网 2、选择以下选项&#xff1a; 3、创建conda 环境&#xff0c;这里python 选择3.9.0&#xff0c;也可以选择其他版本&#xff1a; conda create -c conda-…

智慧交通:构建智慧城市的重要一环

随着信息技术的飞速发展&#xff0c;智慧城市已成为现代城市发展的重要方向。作为智慧城市的重要组成部分&#xff0c;智慧交通以其高效、便捷、环保的特性&#xff0c;成为推动城市现代化进程的关键力量。本文将从智慧交通的概念、发展现状、面临挑战以及未来趋势等方面&#…

在一个程序页面中加几个字段用于增删改查

文章目录 前言一、单表步骤1&#xff1a;更新实体类步骤2&#xff1a;更新DAO层XML步骤3&#xff1a;更新Service实现类步骤4&#xff1a;更新Controller层步骤5&#xff1a;更新前端Vue模型和组件 二、多表步骤1&#xff1a;新程序的增删改查步骤2&#xff1a;老程序中新增实体…

学习python笔记:7,操作excel表格,生成柱状图,

注意&#xff1a; 注意xlsx的格式&#xff0c;wps一定另存为xlsx才可以&#xff0c;不然就出错。 操作表格 1&#xff0c;在终端里面安装openpyxl pip install openpyxl import openpyxl as xl from openpyxl.chart import BarChart,Reference#注意xlsx的格式&#xff0c;wps…

MySQL语法分类 DDL(1)

DDL&#xff08;1&#xff09;(操作数据库、表) 数据库操作(CRUD) C(Create):创建 //指定字符集创建 create database db_1 character set utf8;//避免重复创建数据库报错可以用一下命令 create database if not exists db_1 character set utf8;R(Retrieve):查询 //查询所…

【DiffusionModel系列】Sora揭底系列模型介绍 (VAE/DDPM/SD/DiT/Sora)

飞书PPT链接 简介 该文档介绍了几种深度学习模型&#xff0c;特别是那些在图像合成和处理方面有显著应用的模型。文档内容涉及变分自编码器&#xff08;VAE&#xff09;、去噪扩散概率模型&#xff08;DDPM&#xff09;、稳定扩散&#xff08;Stable Diffusion&#xff09;、…