算法
Ruihai-W
这个作者很懒,什么都没留下…
展开
-
维护两个维度同时递增递减的思想
题目:有个马戏团正在设计叠罗汉的表演节目,一个人要站在另一人的肩膀上。出于实际和美观的考虑,在上面的人要比下面的人矮一点且轻一点。已知马戏团每个人的身高和体重,请编写代码计算叠罗汉最多能叠几个人。思想:需要同时维护两个维度(身高、体重)同时递增。将两个维度合并成一组数据,并将一个维度按升序排序(当该维度中多个值相等时,将另一维度按降序排序)。接下来的任务便是再另一个维度中找出最长升序子序列。其方法是维护一个递增dp数组。对于当前扫描元素i来讲,当i的体重大于dp最后一个元素时,dp数组直接添加i的体重。原创 2021-11-26 13:39:27 · 235 阅读 · 0 评论 -
将相关联的列表进行整合
题目:如给定如下列表:synonyms = ["(Jon,John)","(John,Johnny)","(Chris,Kris)","(Chris,Christopher)"]。现将有关联的名字整合在一起,即整合后的结果为:[(Jon,John,Johnny),(Chris,Kris,Christopher)]。 def find(pre_k, k, ks): if not syn_dic[k]: return原创 2021-11-26 12:10:37 · 316 阅读 · 0 评论 -
Trie(前缀树)
Trie,又称前缀树或字典树,是一棵有根树,其每个节点包含以下字段:指向子节点的指针数组 children。布尔字段 isEnd,表示该节点是否为字符串的结尾。插入字符串我们从字典树的根开始,插入字符串。对于当前字符对应的子节点,有两种情况:子节点存在。沿着指针移动到子节点,继续处理下一个字符。子节点不存在。创建一个新的子节点,记录在 children 数组的对应位置上,然后沿着指针移动到子节点,继续搜索下一个字符。重复以上步骤,直到处理字符串的最后一个字符,然后将当前节点标记为字符串转载 2021-11-24 13:06:13 · 232 阅读 · 0 评论 -
汉诺塔问题
在经典汉诺塔问题中,有 3 根柱子及 N 个不同大小的穿孔圆盘,盘子可以滑入任意一根柱子。一开始,所有盘子自上而下按升序依次套在第一根柱子上(即每一个盘子只能放在更大的盘子上面)。移动圆盘时受到以下限制:(1) 每次只能移动一个盘子;(2) 盘子只能从柱子顶端滑出移到下一根柱子;(3) 盘子只能叠在比它大的盘子上。思路:N个盘子时:(1)将N-1个盘子从A经过C移动到B(2)将第N个盘子从A移动到C(3)将N-1个盘子从B经过A移动到Cclass Solution: def原创 2021-11-23 10:44:21 · 229 阅读 · 0 评论 -
差分数组思想
问题背景:如果给你一个包含5000万个元素的数组,然后会有频繁区间修改操作,那什么是频繁的区间修改操作呢?比如让第1个数到第1000万个数每个数都加上1,而且这种操作时频繁的。此时你应该怎么做?很容易想到的是,从第1个数开始遍历,一直遍历到第1000万个数,然后每个数都加上1,如果这种操作很频繁的话,那这种暴力的方法在一些实时的系统中可能就拉跨了。差分数组思想:假设原数组为arr,差分数组为d,则d[i]=arr[i]-arr[i-1],当我们再次对一个区间内的数组进行操作时,如让第100个数到第500原创 2021-11-21 11:04:18 · 419 阅读 · 0 评论 -
寻找重复数
问题:给定一个包含n + 1 个整数的数组nums ,其数字都在 1 到 n之间(包括 1 和 n),可知至少存在一个重复的整数。假设 nums 只有 一个重复的整数 ,找出 这个重复的数 。你设计的解决方案必须不修改数组 nums 且只用常量级 O(1) 的额外空间。思路:利用循环链表寻找环入口的方法进行求解。如给定数组:[1,3,4,2,2]。可得链表:class Solution: def findDuplicate(self, nums: List[int]) ->...原创 2021-11-05 14:52:58 · 86 阅读 · 0 评论 -
最大矩形问题
1. 柱状图中的最大矩形:给定n个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。求在该柱状图中,能够勾勒出来的矩形的最大面积。思路:从左到右遍历高度,将高度存入栈中,如果当前高度小于栈顶元素,可计算出该栈顶元素所能取得的最大面积,并将该栈顶元素弹出,继续比较下一个栈顶元素与当前高度,直至栈顶元素小于当前高度。当前元素小于栈顶元素时,直接将该高度入栈。遍历完所有元素后,依次弹出栈顶元素,计算该高度对应的面积。class Solution: def la...原创 2021-11-02 11:29:10 · 215 阅读 · 0 评论 -
常见链表问题
1. 倒数第K个元素。思路:设有两个指针 p 和 q,初始时均指向头结点。首先,先让 p 沿着 next 移动 k 次。此时,p 指向第 k+1个结点,q 指向头节点,两个指针的距离为 k 。然后,同时移动 p 和 q,直到 p 指向空,此时 q 即指向倒数第 k 个结点。2. 获取链表中间元素。思路:设有两个指针 fast 和 slow,初始时指向头节点。每次移动时,fast向后走两次,slow向后走一次,直到 fast 无法向后走两次(此时fast.next = None 或 fast.ne原创 2021-10-28 21:23:06 · 148 阅读 · 0 评论 -
回溯算法题
1. 括号生成:数字n代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且有效的括号组合。有效括号组合需满足:左括号必须以正确的顺序闭合。输入:n = 3输出:["((()))","(()())","(())()","()(())","()()()"]class Solution: def generateParenthesis(self, n: int) -> List[str]: self.n = n def backtra...原创 2021-10-25 22:29:36 · 187 阅读 · 0 评论 -
寻找两个正序数组的中位数
题目:将两个数组合并为一个有序数组,若数组长度为奇数,中位数为数组中间的数,若数组长度为偶数,中位数为数组中间两个数的平均值。思路:先计算出中位数是第几小的数,假设为第k小的数,由于两个数组分别是正序数组,所以可以对半的去除k/2个数。class Solution: def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float: l1 = len(nums1)原创 2021-10-24 11:53:22 · 156 阅读 · 0 评论 -
表示数值的字符串
题目:判断给定的字符串是否可以表示数值。部分数值列举如下:["+100", "5e2", "-123", "3.1416", "-1E-16", "0123"]部分非数值列举如下:["12e", "1a3.14", "1.2.3", "+-5", "12e+5.4"]解题思路:创建状态机,根据当前的字否判断接下来可以接哪些字符。遍历字符串,如果出现的字符不在当前状态内,则输出False。难点是状态机的建立,需要根据前序状态确定当前位置合法的字符。class Solutio.原创 2021-10-18 11:57:24 · 73 阅读 · 0 评论 -
摩尔投票法
摩尔投票法:即相同则加,不同则减。利用摩尔投票法求数组中的众数,也就是数量超过数组一班的数。思路:假设众数为数组第一个数num,用count表示此时有几个num,count初始值为1。从第二个数开始遍历数组,如果与假设的众数一样,count += 1。如果不一样,则count -= 1。当count == -1的时候,我们将数组中此时遍历到的数设为众数num,count = 1。继续向后遍历数组。因此,遍历完数组后num的值就是众数。class Solution: def majori原创 2021-09-26 13:27:35 · 156 阅读 · 0 评论 -
旋转正方向矩阵
思路:找规律,看旋转前后的矩阵中的元素坐标的对应关系class Solution: def spiralOrder(self, matrix): n = len(matrix) m = len(matrix[0]) for i in range(0,(n+1)//2): for j in range(m-1-i,i,-1): matrix[i][j], matrix[j][n-1-i] =原创 2021-09-25 10:50:50 · 137 阅读 · 0 评论 -
除自身以外数组的乘积
输入: [1,2,3,4]输出: [24,12,8,6]思路:每个元素的乘积可以分为前缀积和后缀积,如“2”的前缀积为“1”,后缀积为“3*4”,“1的前缀积为”1“,”4“的后缀积为”1“,因此,可以先正向遍历数组,求出每个元素的前缀积,再逆向遍历数组,求每个元素的后缀积,最后将每个元素的前缀积于后缀积相乘便是该元素除自身外的乘积。class Solution: def productExceptSelf(self, nums): answer = [0 for _ .原创 2021-09-25 08:40:33 · 178 阅读 · 0 评论 -
反转字符串中的单词
给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。输入:"Let's take LeetCode contest"输出:"s'teL ekat edoCteeL tsetnoc"class Solution: def reverseWords(self, s): s_new = [] for word in s.split(" "): re_word = word[::-1]原创 2021-09-24 23:01:44 · 85 阅读 · 0 评论 -
数据的排序方法
1. 冒泡排序:时间复杂度O(n^2),空间复杂度O(1),稳定思路:(1)列表每两个相邻的数,如果前面比后面的大,则交换两个数的位置 (2)一趟排序完成后,别找出当前列表中的最大数,并放在当前列表的末尾def bubble_sort(list_num): n = len(list_num) for i in range(n-1): # i 代表第几趟,每排完一趟后,列表后面的有序数组便增加一个数 flag_change = Fals...原创 2021-09-22 15:58:51 · 1328 阅读 · 0 评论 -
数据的查找方法
1. 线性查找,时间复杂度O(n).def linear_search(str_num, target): for i,val in str_num: if val == target: return i else: return False2. 二分查找,时间复杂度O(logn).def Bi_search(str_num, target): left = 0 right = len(str_num)原创 2021-09-22 09:53:09 · 1027 阅读 · 0 评论 -
栈和队列思想
1. 利用栈思想判断给定的一串括号是否左右匹配。思路:如果字符是左括号,则存入栈,如果是右括号,判断栈顶括号是否与它匹配,匹配的话弹出,如果不匹配或者遍历完括号串后栈不为空,说明该串括号不是左右匹配。def bracket_match(str_s): if not str_s: return None dict_match = {'(':')','[':']','{':'}'} bracket = [] for ch in str_s:原创 2021-09-22 08:31:57 · 251 阅读 · 0 评论 -
AVL数的建立
AVL数是一棵自平衡的二叉搜索树。数的每一个节点的左右子树高度差绝对值不能超过1.如果某一个节点的左右子树的高度差绝对值等于2时,则二叉树需要自平衡操作:class BiTreeNode(): # 定义二叉树型节点 def __init__(self,val): self.data = val self.lchild = None self.rchild = None self.pa...原创 2021-09-21 15:51:41 · 385 阅读 · 0 评论 -
二叉树深度的计算
1. 最大深度:根节点到最远叶子节点路径上的节点数:def maxdepth(root): if not root: return 0 if not root.rchild and not root.lchild: return 1 else: ml = maxdepth(root.lchild) ml += 1 mr = maxdepth(root.rchild) mr += 1原创 2021-09-20 13:13:52 · 4580 阅读 · 0 评论 -
二叉搜索树
二叉搜索树是二叉树的一种,其特点是每一个节点的左子树的元素都小于该节点,每一个节点的右子树的元素都大于该节点。因此,使用中序遍历二叉搜索树时,得到的是一个递增序列。class BiTreeNode: # 定义一个二叉树型节点 def __init__(self, val): self.data = val self.lchild = None self.rchild = None self.parent原创 2021-09-20 11:50:16 · 66 阅读 · 0 评论 -
二叉树的遍历
二叉树的时间复杂度是O(logn)。1. 满二叉树:2. 完全二叉树:除去最后一层外,完全二叉树是一棵满二叉树,最后一层的所以节点连续集中于左边。3. 二叉树的建立与遍历:class BiTreeNode: # 定义一个二叉树型节点 def __init__(self, val): self.data = val self.lchild = None self.rchild = None ..原创 2021-09-19 22:24:54 · 1258 阅读 · 0 评论 -
对矩阵进行类卷积操作
给定一个矩阵,对其进行类卷积操作。如对相邻4个元素进行操作得到一个目标值,该操作通常包括求取最大值、最小值、第几个值、求平均等。初次读题,直观的会考虑如何对大矩阵进行相应小块的选取,即如何设置循环来实现每一小块的遍历。思路:其实我们可以从小矩阵出发来对大矩阵进行操作,小矩阵的每一个元素都是由大矩阵的相对应矩阵块求得的,因此由小矩阵的坐标来推大矩阵块的坐标要容易很多。如下面这道题:有维度为2^n*2^n矩阵,对于一个2*2的小矩阵快,取这4个元素中第二大的值作为该矩阵快的值,直到矩阵最后只剩一个元原创 2021-09-19 01:21:55 · 332 阅读 · 0 评论 -
背包问题相关
1. 分数背包问题:给定一些商品的重量与价格goods[],以及书包最大可承受重量W,如何分配背包,是价格最大化。需要注意的是,分数背包问题可以拿走一个商品的一部分,并不是要不都拿,要不不拿。该类问题属于贪心问题。思路:将goods按单价从高到底排序,先从最贵的开始拿,知道背包装满位置。class Solution: def Fractional_backpack(self, goods, w): pick = [0 for _ in range(len(goods))]原创 2021-09-18 12:46:00 · 226 阅读 · 0 评论 -
动态规划问题
1. 上楼梯问题:一共有n阶楼梯,一次只能上1阶或2阶楼梯,问上n阶楼梯一共有多少种方法?思路:假设一共有10阶楼梯,则完成第9阶楼梯时,再上1阶就可以完成10阶楼梯。当完成第8阶楼梯时,再上2阶也可以完成(如果上1阶,则来到第9阶楼梯,该情况已包含在完成9阶楼梯里)。因此,上10阶楼梯的方法F(10)就等于上8阶楼梯的方法加上9阶楼梯的方法,即F(10) = F(9) + F(8)。class Solution: def Step_up_re(self, n): # 递归方法原创 2021-09-17 19:04:41 · 1372 阅读 · 0 评论 -
利用双指针方法求解字符串相关问题
1. 删除数组中指定元素。两个指针从数组第一个元素开始,快指针用于遍历数组,当遇到非删除元素时,将值放于慢指针位置,满指针指向下一个位置。当遇到删除元素时,慢指针不变,快指针继续向后遍历。慢指针之前的值即为需要保留的元素。class Solution: def delEle(self, list_str, k): # write code here if not list_str: return 0 p, q = -1,原创 2021-09-16 10:12:13 · 284 阅读 · 0 评论 -
字符串匹配问题
字符串匹配问题:即给定两个字符串:主串:A(m)和模式串B(n)。判断B是否在A中,并返回B在A中第一次出现的位置。如果不是则返回None原创 2021-09-13 09:50:43 · 1087 阅读 · 0 评论 -
求数组中和为目标值2个数、3个数
给定一个数组arr和一个值k,求数组中和为k的两个数,并返回这两个数的下标。class Solution: def FindMaxLenOfSubStr(self, arr, k): for i, v in enumerate(arr): res = arr[:i] if (k-v) in res: j = res.index(k-v) return j,i原创 2021-09-12 09:26:07 · 538 阅读 · 0 评论 -
滑动窗口思想
给定一个数组arr和一个值s,求arr中和>=s的最短连续子数组。该问题同样属于窗口移动问题。定义一个窗口数组window[],用来储存当前计算的数组。定义另一个数组list_str[],用来储存当前符合条件的最短连续子数组。当窗口内数组和<s时,窗口右边界向右移动。当窗口内数组和>=s时,窗口左边界像右移动。class Solution: def FindMaxLenOfSubStr(self, arr, s): window = [] li原创 2021-09-12 08:43:54 · 112 阅读 · 0 评论 -
子数组求和问题
给定一个数组arr以及整数k,求数组arr中和为k的最长子数组(子数组在arr中是连续的)。核心思想:设数组arr前i个值的和为S(i),则arr[j:i]的和为S(i)-S(j-1)。因此,设置两个列表list_sum和list_index,list_sum用于存储arr前n个数的和,list_index为第n个数在arr中的位置。当S(i)-k 在list_sum中时,那么假设此时list_sum中值在list_index中对应的位置为j。则一个符号要求的子数组为arr[j+1:i+1]。c.原创 2021-09-11 19:16:27 · 467 阅读 · 0 评论