河南网站建设yijuce关于市场营销的案例
- 作者: 五速梦信息网
- 时间: 2026年03月21日 10:54
当前位置: 首页 > news >正文
河南网站建设yijuce,关于市场营销的案例,东莞房价多少,怎样开发手机网站建设1 移掉 K 位数字 1.1 题目描述 题目链接#xff1a;https://leetcode.cn/problems/remove-k-digits/ 1.2 思路分析 这道题让我们从一个字符串数字中删除 k 个数字#xff0c;使得剩下的数最小。也就说#xff0c;我们要保持原来的数字的相对位置不变。 以题目中的 num1432…1 移掉 K 位数字 1.1 题目描述 题目链接https://leetcode.cn/problems/remove-k-digits/ 1.2 思路分析 这道题让我们从一个字符串数字中删除 k 个数字使得剩下的数最小。也就说我们要保持原来的数字的相对位置不变。 以题目中的 num1432219k3num 1432219k 3num1432219k3 为例我们需要返回一个长度为 4 的字符串问题在于 我们怎么才能求出这四个位置依次是什么呢 暴力法的话我们需要枚举 Cn(n−k)C_n^(n - k)Cn(n−k) 种序列其中 nnn 为数字长度并逐个比较最大。这个时间复杂度是指数级别的必须进行优化。 一个思路是 从左到右遍历对于每一个遍历到的元素我们决定是丢弃还是保留 问题的关键是我们怎么知道一个元素是应该保留还是丢弃呢 这里有一个前置知识对于两个数 123a456 和 123b456如果 a b 那么数字 123a456 大于 数字 123b456否则数字 123a456 小于等于数字 123b456。也就说两个相同位数的数字大小关系取决于第一个不同的数的大小。 因此我们的思路就是 从左到右遍历对于遍历到的元素我们选择保留。但是我们可以选择性丢弃前面相邻的元素。丢弃与否的依据如上面的前置知识中阐述中的方法。 以题目中的 num1432219k3num 1432219k 3num1432219k3 为例的图解过程如下 由于没有左侧相邻元素因此没办法丢弃。 由于 4 比左侧相邻的 1 大。如果选择丢弃左侧的 1那么会使得剩下的数字更大开头的数从 1 变成了 4。因此我们仍然选择不丢弃。 由于 3 比左侧相邻的 4 小。 如果选择丢弃左侧的 4那么会使得剩下的数字更小开头的数从 4 变成了 3。因此我们选择丢弃。 后面的思路类似这里就不继续分析啦。 然而需要注意的是如果给定的数字是一个单调递增的数字那么我们的算法会永远选择不丢弃。这个题目中要求的我们要永远确保丢弃 k 个矛盾。 一个简单的思路就是 每次丢弃一次k 减去 1。当 k 减到 0 我们可以提前终止遍历。而当遍历完成如果 k 仍然大于 0。不妨假设最终还剩下 x 个需要丢弃那么我们需要选择删除末尾 x 个元素。 上面的思路可行但是稍显复杂。 我们需要把思路逆转过来。刚才我的关注点一直是丢弃题目要求我们丢弃 k 个。反过来说不就是让我们保留 n−kn - kn−k 个元素么其中 n 为数字长度。 那么我们只需要按照上面的方法遍历完成之后再截取前 n−kn - kn−k 个元素即可。 按照上面的思路我们来选择数据结构。由于我们需要保留和丢弃相邻的元素因此使用栈这种在一端进行添加和删除的数据结构是再合适不过了我们来看下代码实现。 class Solution(object):def removeKdigits(self, num, k):stack []remain len(num) - kfor digit in num: # 构建单调递增的数字串while k and stack and stack[-1] digit:stack.pop()k - 1stack.append(digit)return .join(stack[:remain]).lstrip(0) or 0 提示 如果题目改成求删除 k 个字符之后的最大数我们只需要将 stack[-1] digit 中的大于号改成小于号即可 2 去除重复字母 2.1 题目描述 题目链接https://leetcode.cn/problems/remove-duplicate-letters/ 2.2 思路分析 与上面题目不同这道题没有一个全局的删除次数 k。而是对于每一个在字符串 s 中出现的字母 c 都有一个 k 值。这个 k 是 c 出现次数 - 1。 沿用上面的知识的话我们首先要做的就是计算每一个字符的 k可以用一个字典来描述这种关系其中 key 为 字符 cvalue 为其出现的次数。 具体算法 建立一个字典。其中 key 为 字符 cvalue 为其出现的剩余次数。从左往右遍历字符串每次遍历到一个字符其剩余出现次数 - 1.对于每一个字符如果其对应的剩余出现次数大于 1我们可以选择丢弃也可以选择不丢弃否则不可以丢弃。是否丢弃的标准和上面题目类似。如果栈中相邻的元素字典序更大那么我们选择丢弃相邻的栈中的元素。 还记得上面题目的边界条件么如果栈中剩下的元素大于 n−kn−kn−k我们选择截取前 n−kn - kn−k 个数字。然而本题中的 k 是分散在各个字符中的因此这种思路不可行的。 不过不必担心。由于题目是要求只出现一次。我们可以在遍历的时候简单地判断其是否在栈上即可。 class Solution:def removeDuplicateLetters(self, s) - int:stack []remain_counter collections.Counter(s)for c in s:if c not in stack:while stack and c stack[-1] and remain_counter[stack[-1]] 0:stack.pop()stack.append©remain_counter[c] - 1return .join(stack)查询给定字符是否在一个序列中存在的方法。根本上来说有两种可能 有序序列 可以二分法时间复杂度大致是 O(N)O(N)O(N)。无序序列 可以使用遍历的方式最坏的情况下时间复杂度为 O(N)O(N)O(N)。我们也可以使用空间换时间的方式使用 NNN 的空间 换取 O(1)O(1)O(1) 的时间复杂度。 由于本题中的 stack 并不是有序的因此我们的优化点考虑空间换时间。而由于每种字符仅可以出现一次这里使用 hashset 即可。 class Solution:def removeDuplicateLetters(self, s) - int:stack []seen set()remain_counter collections.Counter(s)for c in s:if c not in seen:while stack and c stack[-1] and remain_counter[stack[-1]] 0:seen.discard(stack.pop())seen.add©stack.append©remain_counter[c] - 1return .join(stack)3 拼接最大数 3.1 题目描述 题目链接https://leetcode.cn/problems/create-maximum-number/ 3.2 思路分析 和第一道题类似只不不过这一次是两个数组而不是一个并且是求最大数。 最大最小是无关紧要的关键在于是两个数组并且要求从两个数组选取的元素个数加起来一共是 k。 然而在一个数组中取 k 个数字并保持其最小或者最大我们已经会了。但是如果问题扩展到两个会有什么变化呢 实际上问题本质并没有发生变化。 假设我们从 nums1 中取了 k1 个从 num2 中取了 k2 个其中 k1 k2 k。而 k1 和 k2 这 两个子问题我们是会解决的。由于这两个子问题是相互独立的因此我们只需要分别求解然后将结果合并即可。 假如 k1 和 k2 个数字已经取出来了。那么剩下要做的就是将这个长度分别为 k1 和 k2 的数字合并成一个长度为 k 的数组合并成一个最大的数组。 以题目的 nums1 [3, 4, 6, 5] nums2 [9, 1, 2, 5, 8, 3] k 5 为例。 假如我们从 num1 中取出 1 个数字那么就要从 nums2 中取出 4 个数字。 运用第一题的方法我们计算出应该取 nums1 的 [6]并取 nums2 的 [9,5,8,3]。 如何将 [6] 和 [9,5,8,3]使得数字尽可能大并且保持相对位置不变呢 实际上这个过程有点类似归并排序中的治而上面我们分别计算 num1 和 num2 的最大数的过程类似归并排序中的分。 我们将从 num1 中挑选的 k1 个数组成的数组称之为 A将从 num2 中挑选的 k2 个数组成的数组称之为 B def merge(A, B):ans []while A or B:bigger A if A B else Bans.append(bigger[0])bigger.pop(0)return ans这里需要说明一下。 在很多编程语言中如果 A 和 B 是两个数组当前仅当 A 的首个元素字典序大于 B 的首个元素A B 返回 true否则返回 false。比如 A [1,2] B [2] A B # TrueA [1,2] B [1,2,3] A B # False以合并 [6] 和 [9,5,8,3] 为例图解过程如下 具体算法 从 nums1 中 取 min(i,len(nums1))min(i, len(nums1))min(i,len(nums1))个数形成新的数组 A取的逻辑同第一题其中 iii 等于 0,1,2, … k。从 nums2 中 对应取 min(j,len(nums2))min(j, len(nums2))min(j,len(nums2)) 个数形成新的数组 B取的逻辑同第一题其中 jjj 等于 k−ik - ik−i。将 A 和 B 按照上面的 merge 方法合并 上面我们暴力了 k 种组合情况我们只需要将 k 种情况取出最大值即可。 class Solution:def maxNumber(self, nums1, nums2, k):def pick_max(nums, k):stack []drop len(nums) - kfor num in nums:while drop and stack and stack[-1] num:stack.pop()drop - 1stack.append(num)return stack[:k]def merge(A, B):ans []while A or B:bigger A if A B else Bans.append(bigger[0])bigger.pop(0)return ansreturn max(merge(pick_max(nums1, i), pick_max(nums2, k-i)) for i in range(k1) if i len(nums1) and k-i len(nums2))小结 这四道题都是删除或者保留若干个字符使得剩下的数字最小或最大或者字典序最小或最大。而解决问题的前提是要有一定数学前提。而基于这个数学前提我们贪心地删除栈中相邻的字符。如果你会了这个套路那么这四个题目应该都可以轻松解决。 参考 不用字符的最小子序列https://leetcode.cn/problems/smallest-subsequence-of-distinct-characters/solutions/290204/yi-zhao-chi-bian-li-kou-si-dao-ti-ma-ma-zai-ye-b-6/
- 上一篇: 河南网站公司自助建站平台便宜
- 下一篇: 河南网站建设yijuce江苏专业网站制作
相关文章
-
河南网站公司自助建站平台便宜
河南网站公司自助建站平台便宜
- 技术栈
- 2026年03月21日
-
河南网站定制番禺人才网最新招聘信息
河南网站定制番禺人才网最新招聘信息
- 技术栈
- 2026年03月21日
-
河南网站备案代理外贸平台做摩托车配件什么网站好
河南网站备案代理外贸平台做摩托车配件什么网站好
- 技术栈
- 2026年03月21日
-
河南网站建设yijuce江苏专业网站制作
河南网站建设yijuce江苏专业网站制作
- 技术栈
- 2026年03月21日
-
河南网站建设公司哪个好呀百度网址大全官方下载
河南网站建设公司哪个好呀百度网址大全官方下载
- 技术栈
- 2026年03月21日
-
河南网站建设价格与方案wordpress阅读时间
河南网站建设价格与方案wordpress阅读时间
- 技术栈
- 2026年03月21日
