数据结构与算法
记录部分LeetCode题解和一些笔面试算法题
明日何其多_
这个作者很懒,什么都没留下…
展开
-
二分法求最值:面向答案编程
思路求最值的算法题一般是贪心或者动规,但也有其他的情况,既找不到局部最优也写不出递推公式,这个时候或许可以尝试一下二分。二分的思路很简单,即面向答案编程。它不关心具体的操作过程,而是先确定答案的范围,二分得到中间值,判断当前值是否满足要求,继续二分直到找到结果。简直是另辟蹊径有木有?例子lc5219. 每个小孩最多能分到多少糖果https://leetcode-cn.com/problems/maximum-candies-allocated-to-k-children/.给你一个 下标从 0原创 2022-04-03 16:02:09 · 1114 阅读 · 0 评论 -
记一道动态规划算法题:0-1背包之两个背包问题
题目描述某公司有一批货物,系了2个轮船进行运输。每条轮船上可以运输不同容量的货物。由于2个轮船的发船时间不一样,同一个货物通过不同的轮船运输到终点后,利润也是不一样的,现在需要根据不同轮船的容量、货物的容量以及在不同轮船上进行运输的利润有效地分配货物,从而达到货物价值最大化。每个货物只有1件。输入:第一行输入为A B M,A代表轮船A的容量,B代表轮船B的容量,M代表货物的个数。之后M行分别代表每个货物的容量、使用轮船A运输的利润、使用轮船B运输的利润。输出:最大利润。例子:输入:5 6原创 2022-01-06 08:54:04 · 2705 阅读 · 1 评论 -
记一道关于堆的算法题
1 题目描述有20个数组,每个数组中有500个数,降序排列,输出这20个数组中最大的500个数。2 解法我开始想的是归并的方法。每个数组用一个指针指向第一个元素,然后比较得到最大值,指向最大值的指针后移,一共循环500次。但是这样的时间复杂度是O(n*k),可以用堆将其降为O(nlogk)。(假如数组有k个,每个数组中有n个元素)具体做法是先取每个数组的首元素建立一个大小为k的大顶堆,pop出最大值保存到res数组,然后push下一个数进去。这里的下一个数就是最大值在数组中的后面一个数。因此我们需要原创 2021-12-06 20:30:24 · 984 阅读 · 0 评论 -
求二进制矩阵中的路径总数(机器人运动,dfs)
题目描述在m×n的二进制矩阵中,1代表不可通过,0代表可通过。机器人从(0,0)出发,每次可向下或向右移动一格。问走到(m-1,n-1)一共有多少条路径?代码def get_path_num(matrix: List[List[int]]) -> int: m,n=len(matrix),len(matrix[0]) total=0 moves=[(1,0),(0,1)] def dfs(x,y): if x==m-1 and y==n-1:原创 2021-09-14 19:20:12 · 134 阅读 · 0 评论 -
LeetCode 1091:二进制矩阵中的最短路径
题目描述给你一个 n x n 的二进制矩阵 grid 中,返回矩阵中最短 畅通路径 的长度。如果不存在这样的路径,返回 -1 。二进制矩阵中的 畅通路径 是一条从 左上角 单元格(即,(0, 0))到 右下角 单元格(即,(n - 1, n - 1))的路径,该路径同时满足下述要求:路径途经的所有单元格都的值都是 0 。路径中所有相邻的单元格应当在 8 个方向之一 上连通(即,相邻两单元之间彼此不同且共享一条边或者一个角)。畅通路径的长度 是该路径途经的单元格总数。解题思路DFS和BFS都可以原创 2021-09-14 13:36:29 · 348 阅读 · 0 评论 -
LeetCode 912:排序数组(快速排序、归并排序和堆排序)
快速排序class Solution: def sortArray(self, nums: List[int]) -> List[int]: def quickSort(l,r): if l>=r: return import random pivot = random.randint(l, r) nums[l], nums[pivot] =原创 2021-09-07 17:08:54 · 1084 阅读 · 0 评论 -
LeetCode 251:数组中的第K个最大元素(快速排序、堆排序)
快速排序快速排序一个典型的分治算法,每次经过「划分」操作后,一定可以确定一个元素的最终位置,并且保证该元素左边的元素都小于等于它,右边的元素都大于等于它。所以只要某次划分的元素位置q为倒数第 k个下标的时候,我们就已经找到了答案。因此我们可以改进快速排序算法来解决这个问题:在分解的过程当中,我们会对子数组进行划分,如果划分得到的 q正好就是我们需要的下标,就直接返回 a[q];如果 q 比目标下标小,就递归右子区间,否则递归左子区间。这样就可以把原来递归两个区间变成只递归一个区间,提高了时间效率。这就是原创 2021-06-15 22:41:19 · 241 阅读 · 2 评论 -
LeetCode 416:分割等和子集(转化为0-1背包问题)
题目描述问题转化可以理解成是否能从给定数组里取出部分元素,使这些元素总和刚好为数组总和的一半。由于没个元素只能使用一次,所以就是0-1背包问题了。二维数组解法确定dp数组及下标含义dp[i][j]表示是否能从下标不大于i的元素中取出部分元素使得这些元素总和刚好为j(值为True或False)。j的范围是0~target,target就是数组总和的一半。递推公式dp[i][j]=dp[i-1][j] or dp[i-1][j-nums[i]]两种选择:1)不使用下标为i的元素,此时dp[原创 2021-05-01 20:57:39 · 201 阅读 · 1 评论 -
LeetCode 322 :零钱兑换(完全背包,二维数组和一维数组两种解法)
题目给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。你可以认为每种硬币的数量是无限的。二维数组解法def coinChange(self, coins: List[int], amount: int) -> int: m=len(coins) n=amount+1 dp=[[float('inf')] * n for i in ra原创 2021-04-26 13:10:45 · 534 阅读 · 1 评论 -
Leetcode刷题技巧总结篇(python版)
持续更新……1 求字符差值python不可以直接进行字符减运算。当需要进行字符之间的减运算时,我们可以用ord()函数。ord()是python自带的函数,无需导入。2 字符串反转string='leetcode'print(string[::-1])3 数组元素计数import collectionsli=[1,2,2,4,5,5]cnt = collections.Counter(li)print(cnt)4 字典遍历cnt={1:4,2:3}# 遍历键值对for原创 2021-04-05 00:08:28 · 11817 阅读 · 1 评论 -
Leetcode230:二叉搜索树中第K小的元素(python版)
题目描述给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 个最小元素(从 1 开始计数)。解题关键二叉排序树的中序遍历是有序的。方法对二叉树进行中序遍历,用count计数,当遍历到第k个节点时将当前节点的值赋给变量re,最后返回re。class Solution: def __init__(self): self.count = 0 self.re=0 def kthSmallest(self, root:原创 2021-03-29 10:46:47 · 344 阅读 · 1 评论 -
Leetcode160:相交链表(相交的定义是什么)
看上面这个例子时我就很疑惑,如果是两个点值相同就是相交,那么1才是交点啊。然后发现不是的,1这个点并不相同,因为前面的节点是不一样的,只有前后节点都一样才算相同。那么就好办了。一个很好理解的方法是先计算出两个链表的长度差d,然后让长的那个先走d步,再让两者同时出发,相遇(节点相同)处即为交点。如果两者皆走到了空值,即不相交。def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode: le.原创 2021-03-27 11:03:21 · 732 阅读 · 1 评论 -
Leetcode11:盛最多水的容器(js版)
题目描述:给你 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。说明:你不能倾斜容器。方法一:双重循环var maxArea = function(height) { var area=0; for(var i = 0; i < height.length;i++){原创 2021-02-14 11:37:52 · 178 阅读 · 1 评论 -
leetcode:整数反转(js版)
var reverse = function (x) { if (x < 0) { return -reverse(-x); } var n = x.toString().length; var i = 0; var y = 0; nums = []; while (x != 0) { y = y + (x % 10) * Math.pow(10, n - i - 1); x = Math.floor(x / 10); i++; }原创 2021-01-29 23:36:04 · 144 阅读 · 0 评论 -
leetcode:最长回文子串(js版)
动态规划的方法。var longestPalindrome = function(s) { var max_len=1; var start=0; var arr=new Array(); for (let j=1;j<s.length;j++){ for(let i=0;i<s.length-1;i++){ arr[i] = new Array(); if(j-i<=2){原创 2021-01-28 18:46:40 · 210 阅读 · 0 评论 -
leetcode:寻找两个正序数组的中位数
语言:js方法:归并排序时间复杂度:遍历全部数组 O(m+n)空间复杂度:开辟了一个数组,保存合并后的两个数组 O(m+n)var findMedianSortedArrays = function (nums1, nums2) { var i=0,j=0,k=0; var num3=new Array(); while(i<nums1.length&&j<nums2.length){ if(nums1[i]>nums2[j]原创 2021-01-24 21:20:20 · 79 阅读 · 0 评论