leetcode 21~30 学习经历

news2025/1/23 17:33:22

leetcode 21~30 学习经历

  • 21. 合并两个有序链表
  • 22. 括号生成
  • 23. 合并K个升序链表
  • 24. 两两交换链表中的节点
  • 25. K 个一组翻转链表
  • 26. 删除有序数组中的重复项
  • 27. 移除元素
  • 28. 找出字符串中第一个匹配项的下标
  • 29. 两数相除
  • 30. 串联所有单词的子串
  • 小结

21. 合并两个有序链表

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
在这里插入图片描述

示例 1:
输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]
示例 2:
输入:l1 = [], l2 = []
输出:[]
示例 3:
输入:l1 = [], l2 = [0]
输出:[0]

提示:
两个链表的节点数目范围是 [0, 50]
-100 <= Node.val <= 100
l1 和 l2 均按 非递减顺序 排列
通过次数1,291,915提交次数1,942,192

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/merge-two-sorted-lists
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

这是个评价为简单的题目,嗯,直接莽过去,没啥算法吧?

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
        r = ListNode()
        n = r
        while list1 or list2:
            if not list1:
                n.next = list2
                break
            if not list2:
                n.next = list1
                break
            if list1.val < list2.val:
                n.next = list1
                n = n.next
                list1 = list1.next
            else:
                n.next = list2
                n = n.next
                list2 = list2.next
        return r.next

大佬们的答案还是有些精巧的内容的,比如头部的递归,没啥好讲的,pass

22. 括号生成

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

示例 1:
输入:n = 3
输出:[“((()))”,“(()())”,“(())()”,“()(())”,“()()()”]
示例 2:
输入:n = 1
输出:[“()”]

提示:
1 <= n <= 8
通过次数651,057提交次数839,224

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/generate-parentheses
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

呦,n的范围只有1-8,这么少用例啊,得,直接暴力搞吧

class Solution:
    def generateParenthesis(self, n: int) -> List[str]:
        if n < 1:
            return ['']
        r = []
        for i in range(1,n + 1):
            t = self.generateParenthesis(n - i)
            for x in t:
                if '(' * i + ')' * i + x not in r:
                    r.append('(' * i + ')' * i + x)
                if '(' * i + x + ')' * i not in r:
                    r.append('(' * i + x + ')' * i)
        return r

啊。。。。答案错误,一看,输入为4的时候,少了个(()())()的输出。。。额。。这就麻烦了
在这里插入图片描述
这个时候,我反应过来了,这个题目没我想的那么简单,递归里还得平衡左右,从新思考吧。。。结果掉递归的坑里出不来了。。。

然后我就又这么考虑了,不管n等于几,一共有n个左括号,然后插入同样数量的右括号,只要保证右括号数量小于左边的左括号数量,那就是另一个办法了,试试看

class Solution:
    def generateParenthesis(self, n: int) -> list[str]:
        if n < 1:
            return ['']
        
        r =self.makeGroup(n,n,'')
        r.sort()
        return r
    
    def makeGroup(self,l,r,s):
        if l == 0:
            return [s + ')' * r]
        arr = []
        for j in range(r-l+1):
            ns = s + ')' * j 
            for i in range(1,l + 1):
                nns = ns + '(' * i
                for item in self.makeGroup(l - i, r - j,nns):
                    if item not in arr:
                        arr.append(item)
        return arr

在这里插入图片描述
马马虎虎弄出了一个,没有优化过的版本就这么累赘,再调整调整,简略一下代码,然后一个很意外的成绩排行出现了

class Solution:
    def generateParenthesis(self, n: int) -> list[str]:
        if n < 1:
            return ['']
        r =sorted(self.makeGroup(n,n,''))
        return r
    def makeGroup(self,l,r,s):
        if l == 0:
            return {s + ')' * r}
        arr = set()
        for j in range(r-l+1):
            for i in range(1,l + 1):
                arr = arr.union(self.makeGroup(l - i, r - j,s + ')' * j + '(' * i))
        return arr

在这里插入图片描述
60ms竟然是倒数的成绩。。。。这。。。。。
在这里插入图片描述
我就直接好家伙。。。。。还是瑟瑟发抖的继续学习吧
56ms的代码。。。把所有可能的组合都扔到list里去了,然后组合?
44ms的代码。。。好像把我的两个循环也变成递归,就可以了?

class Solution:
    def generateParenthesis(self, n: int) -> list[str]:
        if n < 1:
            return ['']
        r =sorted(self.makeGroup(n,n,''))
        return r
    def makeGroup(self,l,r,s):
        print(l,r,s)
        if l == 0:
            return {s + ')' * r}
        arr = set()
        if l > 0:
            arr = arr.union(self.makeGroup(l - 1,r, s + '('))
        if r > l:
            arr = arr.union(self.makeGroup(l,r - 1, s + ')'))
        return arr

在这里插入图片描述
果然效率又高了一点点。。。。后边再看30ms以下的大佬们的答案,嗯比我效率高是应当的,人直接没用集合,不用并集去重就能得到答案,这是算法生成的问题,不是程序的问题了。。。

总之,这个题目耗费的时间有点出乎预料,中间还走错了几步路,还是要好好夯实基础啊

23. 合并K个升序链表

给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。

示例 1:
输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
1->4->5,
1->3->4,
2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6
示例 2:
输入:lists = []
输出:[]
示例 3:
输入:lists = [[]]
输出:[]

提示:
k == lists.length
0 <= k <= 10^4
0 <= lists[i].length <= 500
-10^4 <= lists[i][j] <= 10^4
lists[i] 按 升序 排列
lists[i].length 的总和不超过 10^4
通过次数602,178提交次数1,045,344

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/merge-k-sorted-lists
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

这个题评价为困难,但感觉做法不难啊,最后一看,lists[i].length的范围。。。。1万个,lists.length。。。500个,也就是最大500万个节点?瑟瑟发抖中。。。

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]:
        z = []
        for node in lists:
            while node:
                z.append(node.val)
                node = node.next
        if len(z) == 0:
            return None
        n = ListNode()
        r = n
        z.sort()
        for i in z:
            n.next = ListNode(i)
            n = n.next
        return r.next

在这里插入图片描述
在这里插入图片描述

额。。。。。直接遍历得到所有值,然后排序,然后生成新的链表,这。。。。合适么?不知道用例中有没有大量的链表数据,感觉一次就过了,有点不真实,这个难度评为困难真是名不符实啊

# 以下内容抄自LeetCode第23题44ms答案
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def mergeKLists(self, lists: List[Optional[ListNode]]) -> Optional[ListNode]:
        ans = []
        for i in lists:
            p = i
            while p:
                ans.append(p)
                p = p.next
        if len(ans) == 0:
            return None
        ans.sort(key = lambda x:x.val)
        for i in range(1,len(ans)):
            ans[i-1].next = ans[i]
        ans[-1].next = None

        return ans[0]

嗯,真不戳,可惜老顾暂时对 linq、lambda之类的指令用不惯,还得继续适应啊

24. 两两交换链表中的节点

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。

示例 1:
输入:head = [1,2,3,4]
输出:[2,1,4,3]
示例 2:
输入:head = []
输出:[]
示例 3:
输入:head = [1]
输出:[1]

提示:
链表中节点的数目在范围 [0, 100] 内
0 <= Node.val <= 100
通过次数579,151提交次数812,197

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/swap-nodes-in-pairs
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

哦吼,又是一个小数据题目,直接暴力上!

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
        if not head or not head.next:
            return head
        r = ListNode(0,head)
        p = r
        while head and head.next:
            n1 = head
            n2 = head.next
            n3 = head.next.next
            p.next = n2
            n2.next = n1
            n1.next = n3
            head = n3
            p = n1
        return r.next

在这里插入图片描述
在这里插入图片描述
这个题,感觉就是交换变量,并保持链表完整,不要断了,老顾这种没玩过链表的,试了两下就做出来了,这是个熟悉链表的题目,入门级,这个中等难度是怎么评的?看了眼20ms大佬的答案,写法基本一致,就是交换和链接更简洁,没什么可说的了

25. K 个一组翻转链表

给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。
k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

示例 1:
输入:head = [1,2,3,4,5], k = 2
输出:[2,1,4,3,5]
示例 2:
输入:head = [1,2,3,4,5], k = 3
输出:[3,2,1,4,5]

提示:
链表中的节点数目为 n
1 <= k <= n <= 5000
0 <= Node.val <= 1000

进阶:你可以设计一个只用 O(1) 额外内存空间的算法解决此问题吗?
通过次数434,044提交次数640,648

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/reverse-nodes-in-k-group
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

额。。。。。题目描述里有什么?改变节点值?我怎么没想到。。。。。合着前几个链表的题,还可以这么作弊完成啊。。。。嗯。。。虽然老顾对链表不熟,但xml玩的还不少,xmlnode改变值意义不大,htmldom 也一样,该移动节点的还是要移动节点,偶尔作弊也就算了,不能一直作弊下去吧。正好,学习了23题大佬的办法,直接用上看看

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reverseKGroup(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
        arr = []
        if not head:
            return None
        parent = ListNode(0,head)
        while head:
            arr.append(head)
            head = head.next
        if len(arr) < k:
            return head
        for i in range(len(arr) // k):
            arr = arr[:i * k] + arr[i * k:(i + 1) * k][::-1] + arr[(i + 1) * k:]
        parent.next = arr[0]
        arr[-1].next = None
        for i in range(len(arr) - 1):
            arr[i].next = arr[i + 1]
        return parent.next

在这里插入图片描述
这还真是会者不难,难者不会了,有大佬的答案打底,这些评价困难的链表题,感觉就和送分题一样了

额。。。。再看了一遍大佬们的答案。。。头部答案全是自己实现 reverse 的。。。。一直在追随大佬们的脚步,一直在吃灰尘。这个仇(手动划掉)。。。方法我记住了

26. 删除有序数组中的重复项

给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。
由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有 k 个元素,那么 nums 的前 k 个元素应该保存最终结果。
将最终结果插入 nums 的前 k 个位置后返回 k 。
不要使用额外的空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

判题标准:
系统会用下面的代码来测试你的题解:
int[] nums = […]; // 输入数组
int[] expectedNums = […]; // 长度正确的期望答案
int k = removeDuplicates(nums); // 调用
assert k == expectedNums.length;
for (int i = 0; i < k; i++) {
assert nums[i] == expectedNums[i];
}
如果所有断言都通过,那么您的题解将被 通过。

示例 1:
输入:nums = [1,1,2]
输出:2, nums = [1,2,_]
解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。
示例 2:
输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5, nums = [0,1,2,3,4]
解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。

提示:
1 <= nums.length <= 3 * 10^4
-10^4 <= nums[i] <= 10^4
nums 已按 升序 排列
通过次数1,394,160提交次数2,549,147

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/remove-duplicates-from-sorted-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

啊。。。。猛的一看好像很简单,直接在 python 里,给 nums 重新赋值一下就好,结果。。。内存地址变了,修改的结果没有进入到原数组,直接失败。。。。。

看来,只能在原数组上修改了,又不想用 pop 方法作弊了,那就仔细琢磨吧

class Solution:
    def removeDuplicates(self, nums: List[int]) -> int:
        if len(nums) < 2:
            return len(nums)
        r = [0 for _ in range(len(nums))]
        z = [0 for _ in range(len(nums))]
        r[0] = nums[0]
        n = 1
        e = 0
        for i in range(1,len(nums)):
            if nums[i] == nums[i - 1]:
                z[e] = nums[i]
                e += 1
            else:
                r[n] = nums[i]
                n += 1
        for i in range(n):
            nums[i] = r[i]
        for i in range(e):
            nums[i + n] = z[i]
        return n

在这里插入图片描述
冒充 python 不支持不定长的数组,呵呵,成绩差强人意,试着用 pop 搞了啊,成绩居然上了1000ms
在这里插入图片描述
果然还是要自己写数组操作啊

class Solution:
    def removeDuplicates(self, nums: List[int]) -> int:
        n = len(nums)
        if n < 2:
            return n
        l,r = 0,1
        while r < n:
            if nums[r] != nums[l]:
                l += 1
                nums[l] = nums[r]
            r += 1
        return l + 1

在这里插入图片描述
直接操作原数组,时间节省了一点点,内存怎么一直这么高?看大佬们的答案去了。。。结果答案和咱现在写法大差不大的一毛一样了,确认是老顾网络和电脑的性能差了

27. 移除元素

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

说明:
为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:
// nums 是以“引用”方式传递的。也就是说,不对实参作任何拷贝
int len = removeElement(nums, val);
// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。
for (int i = 0; i < len; i++) {
print(nums[i]);
}

示例 1:
输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。
示例 2:
输入:nums = [0,1,2,2,3,0,4,2], val = 2
输出:5, nums = [0,1,4,0,3]
解释:函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。

提示:
0 <= nums.length <= 100
0 <= nums[i] <= 50
0 <= val <= 100
通过次数957,786提交次数1,612,276

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/remove-element
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

这题目和上边那个26很类似啊,一个是排重,一个是删指定值,还是直觉题,倒是数组是引用的进行了说明,26题里还是隐藏条件呢

class Solution:
    def removeElement(self, nums: List[int], val: int) -> int:
        n = len(nums)
        z = 0
        pos = 0
        while pos < n:
            if z > 0:
                nums[pos - z] = nums[pos]
            if nums[pos] == val:
                z += 1
            pos += 1
        return n - z

在这里插入图片描述
只要记录了删了几个数据,然后将数据回移就可以了,没什么可说的,自信这题,大佬也就这样,题目难度上限太低,体现不出大佬的能力

28. 找出字符串中第一个匹配项的下标

给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。

示例 1:
输入:haystack = “sadbutsad”, needle = “sad”
输出:0
解释:“sad” 在下标 0 和 6 处匹配。
第一个匹配项的下标是 0 ,所以返回 0 。
示例 2:
输入:haystack = “leetcode”, needle = “leeto”
输出:-1
解释:“leeto” 没有在 “leetcode” 中出现,所以返回 -1 。

提示:
1 <= haystack.length, needle.length <= 10^4
haystack 和 needle 仅由小写英文字符组成
通过次数798,403提交次数1,898,322

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/find-the-index-of-the-first-occurrence-in-a-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

这题评价是中等,那我下边这个就是来搞笑的了

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        if haystack.count(needle) > 0:
            return haystack.index(needle)
        else:
            return -1

在这里插入图片描述
这是要求自己写匹配啊,问题是,除了c,其他哪个语言没有字符串截取函数呢?substring、substr、[i:j]之类的,用了这个,也和上边差不多了啊

class Solution:
    def strStr(self, haystack: str, needle: str) -> int:
        for i in range(len(haystack) - len(needle) + 1):
            if haystack[i:i+len(needle)] == needle:
                return i
        return -1

在这里插入图片描述
20ms大佬还真的用字符比较的方式完成的。佩服
另一个也是偷懒的答案,用find
在这里插入图片描述

29. 两数相除

给你两个整数,被除数 dividend 和除数 divisor。将两数相除,要求 不使用 乘法、除法和取余运算。
整数除法应该向零截断,也就是截去(truncate)其小数部分。例如,8.345 将被截断为 8 ,-2.7335 将被截断至 -2 。
返回被除数 dividend 除以除数 divisor 得到的 商 。
注意:假设我们的环境只能存储 32 位 有符号整数,其数值范围是 [−2^31, 2^31 − 1] 。本题中,如果商 严格大于 2^31 − 1 ,则返回 2^31 − 1 ;如果商 严格小于 -2^31 ,则返回 -2^31 。

示例 1:
输入: dividend = 10, divisor = 3
输出: 3
解释: 10/3 = 3.33333… ,向零截断后得到 3 。
示例 2:
输入: dividend = 7, divisor = -3
输出: -2
解释: 7/-3 = -2.33333… ,向零截断后得到 -2 。

提示:
-2^31 <= dividend, divisor <= 2^31 - 1
divisor != 0
通过次数199,432提交次数898,008

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/divide-two-integers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

额。。。我的第一个暴力解法直接超时了,毕竟不用乘除和取余,人给了个很大的被除数,绝对值很小的除数。。。用循环减的办法直接pass。那么,这个题目明显就是要考二进制除法了,这真难为老顾了,毕竟野路子搞出来的,完全没学过理论,平时就完全用不上二进制啊。先补课学下二进制再继续。

一段时间过去了,然后了解到 python 里的位移,然后就会做了,尽管代码很累赘

class Solution:
    def divide(self, dividend: int, divisor: int) -> int:
        n = 0
        f = 1 # 默认是正数
        if divisor < 0:
            f = 0 - f
            divisor = 0 - divisor
        if dividend < 0:
            f = 0 - f
            dividend = 0 - dividend
        m = [0] # 存放位移的次数和位移的数量
        while dividend >= divisor:
            d = divisor
            while dividend > d << 1:
                d = d << 1
                m[-1] += 1
            dividend -= d
            m.append(0)
        for i in range(len(m) - 1):
            n += 1 << m[i] # 将位移的结果相加,就是商
        if f < 0: # 补上符号
            n = 0 - n
        mx = 2 ** 31 -1
        mn = -2 ** 31
        n = n if n < mx else mx
        n = n if n > mn else mn
        return n

在这里插入图片描述
在这里插入图片描述
然后看大佬的答案
在这里插入图片描述
这个思路不错,是我的了,拿来吧您呐
24ms的答案思路清奇。。。。这个拿不过来。。。感觉不如用28ms大佬的实用和泛用

30. 串联所有单词的子串

给定一个字符串 s 和一个字符串数组 words。 words 中所有字符串 长度相同。
s 中的 串联子串 是指一个包含 words 中所有字符串以任意顺序排列连接起来的子串。
例如,如果 words = [“ab”,“cd”,“ef”], 那么 “abcdef”, “abefcd”,“cdabef”, “cdefab”,“efabcd”, 和 “efcdab” 都是串联子串。 “acdbef” 不是串联子串,因为他不是任何 words 排列的连接。
返回所有串联字串在 s 中的开始索引。你可以以 任意顺序 返回答案。

示例 1:
输入:s = “barfoothefoobarman”, words = [“foo”,“bar”]
输出:[0,9]
解释:因为 words.length == 2 同时 words[i].length == 3,连接的子字符串的长度必须为 6。
子串 “barfoo” 开始位置是 0。它是 words 中以 [“bar”,“foo”] 顺序排列的连接。
子串 “foobar” 开始位置是 9。它是 words 中以 [“foo”,“bar”] 顺序排列的连接。
输出顺序无关紧要。返回 [9,0] 也是可以的。
示例 2:
输入:s = “wordgoodgoodgoodbestword”, words = [“word”,“good”,“best”,“word”]
输出:[]
解释:因为 words.length == 4 并且 words[i].length == 4,所以串联子串的长度必须为 16。
s 中没有子串长度为 16 并且等于 words 的任何顺序排列的连接。
所以我们返回一个空数组。
示例 3:
输入:s = “barfoofoobarthefoobarman”, words = [“bar”,“foo”,“the”]
输出:[6,9,12]
解释:因为 words.length == 3 并且 words[i].length == 3,所以串联子串的长度必须为 9。
子串 “foobarthe” 开始位置是 6。它是 words 中以 [“foo”,“bar”,“the”] 顺序排列的连接。
子串 “barthefoo” 开始位置是 9。它是 words 中以 [“bar”,“the”,“foo”] 顺序排列的连接。
子串 “thefoobar” 开始位置是 12。它是 words 中以 [“the”,“foo”,“bar”] 顺序排列的连接。

提示:
1 <= s.length <= 10^4
1 <= words.length <= 5000
1 <= words[i].length <= 30
words[i] 和 s 由小写英文字母组成
通过次数153,336提交次数387,214

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/substring-with-concatenation-of-all-words
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

哦,又一个最大组合可能,且寻找组合子项

一段时间过去了。。。。连续提交超时,有一个用例, words 数量18 个,这要组合出来。。。6402373705728000种可能?得嘞,这题考的不是排列组合了,换个思路吧

活用字典就好

class Solution:
    def findSubstring(self, s: str, words: List[str]) -> List[int]: 
        d = set(words)
        p = sorted(words)
        m = len(words)
        n = len(words[0])
        z = []
        for i in range(len(s) - m * n + 1):
            if s[i:i + n] not in d:
                continue
            q = sorted([s[_ * n + i:(_ + 1) * n + i] for _ in range(m)])
            if p == q:
                z.append(i)
        return z

在这里插入图片描述
居然还在前一半里,我还以为排不上呢。整个思路就是,从任意位置判断,单词长度的字符串在不在words里,不在就不说了,在的话,取出同样数量的字串和 words 比较,我就不管你怎么组合了,直接看字符串能对不对的上就完了,本来是想用 set 差的,结果words里有重复的字符串。。。

结果,就这个思路下去的话,应该没办法优化执行时间了,去抄大佬们的思路看看,然后发现大佬们在用 collections 包,这。。。。python 不熟啊,纯粹兴趣,没用他工作过啊,包更不熟啊。。。算了,没有外部因素,估计300ms就是极限了。记下这个恨,以后再来报复。

小结

又10题做完了,感觉还是基础不牢。二进制居然还要回想补课,多简单的操作;括号生成也卡了一下,写了一片无用代码还没能完成;链表也才开始接触,还有很多需要学习的内容。
那么今天就到这里,下次继续刷题。
在这里插入图片描述

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

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

相关文章

15. Qt中OPenGL的参数传递问题

1. 说明 在OPenGL中&#xff0c;需要使用GLSL语言来编写着色器的函数&#xff0c;在顶点着色器和片段着色器之间需要参数值的传递&#xff0c;且在CPU中的数据也需要传递到顶点着色器中进行使用。本文简单介绍几种参数传递的方式&#xff1a; &#xff08;本文内容仅个人理解&…

学校节能减排实施方案-浅析高校能耗及节能管理

摘要:高校能源管理是高校治理体系和高校后勤保障的重要组成部分。利用数据统计等手段对蚌埠医学院近年来的能源使用情况进行统计分析&#xff0c;通过横向及纵向对比&#xff0c;结合国家相关政策法规及同类高校能耗情况&#xff0c;对该校能源消耗现状进行了综合分析&#xff…

Web3中文|2023年zk赛道爆发,即将推出的Polygon zkEVM有多重要?

Crypto行业被广泛关注的零知识证明&#xff08;Zero—Knowledge Proof&#xff09;技术&#xff0c;在1980年就被数学家S.Goldwasser、S.Micali及C.Rackoff提出。 零知识证明涉及一系列步骤&#xff0c;可以实现密码学中的「可用而不可知」。 而区块链有着公开透明、不可篡改…

Nginx之反向代理、负载均衡、动静分离。

Nginx之反向代理、负载均衡、动静分离。 1、Nginx是啥&#xff1f; 轻量级Web服务器、反向代理服务器、电子邮件&#xff08;IMAP/POP3&#xff09;代理服务器 在 BSD-like 协议下发行、占内存少、并发高&#xff08;同时处理请求能力&#xff09;。 2、安装 官网&#xf…

【Python】序列与列表(列表元素的增删改查,求之,列表推导式、列表的拷贝)

一、序列序列的概念&#xff1a;按照某种顺序排列的数据类型就叫做序列&#xff0c;比如字符串&#xff0c;列表&#xff0c;元组&#xff0c;集合序列的共同点是都有下标&#xff0c;支持index()方法和count()&#xff0c;也支持切片处理(等同于字符串序列的切片处理)l1 [0, …

Leetcode(每日一题)——1140. 石子游戏 II

摘要 ​​​​​​1140. 石子游戏 II 877. 石子游戏 1406. 石子游戏 III 375. 猜数字大小 II 464. 我能赢吗 486. 预测赢家 1025. 除数博弈 一、动态规划解析 Alice一开始有两个选择&#xff1a;拿前一堆/前两堆石子。如果 Alice 拿前一堆&#xff0c;那么轮到 Bob 时…

Propargyl-PEG1-SS-PEG1-PFP ester,1817735-30-0,炔基应用于生物标记

【中文名称】丙炔-单乙二醇-二硫键-单乙二醇-五氟苯酚酯【英文名称】 Propargyl-PEG1-SS-PEG1-PFP ester【结 构 式】【CAS号】1817735-30-0【分子式】C16H15F5O4S2【分子量】430.4【基团部分】炔基基团【纯度标准】95%【包装规格】1g&#xff0c;5g&#xff0c;10g&#xff0c…

互联网行业中,哪些岗位越老越吃香?

你是不是也想转行IT行业&#xff0c;找一门适合自己学习&#xff0c;能拿高薪的技术&#xff0c;最好还越老越吃香&#xff1f;或许先应该看看对应岗位&#xff0c;老资格的同行们可以拿到的薪资数再做判断。整体上看&#xff0c;大部分岗位的起薪水平相差不大&#xff0c;但随…

matplotlib绘制三维图

目录线状堆积图 PolygonPlot三维表面图 SurfacePlot散点图ScatterPlot柱形图 BarPlot三维直方图螺旋曲线图 LinePlotContourPlot轮廓图网状图 WireframePlot箭头图二维三维合并文本图Text三维多个子图线状堆积图 PolygonPlot Axes3D.add_collection3d(col, zs0, zdir‘z’)  …

(考研湖科大教书匠计算机网络)第六章应用层-第一、二节:应用层概述和C/S及P2P

获取pdf&#xff1a;密码7281专栏目录首页&#xff1a;【专栏必读】考研湖科大教书匠计算机网络笔记导航 文章目录一&#xff1a;应用层概述二&#xff1a;客户/服务器&#xff08;C/S&#xff09;和对等&#xff08;P2P&#xff09;方式&#xff08;1&#xff09;客户/服务器&…

Vue页面组成及常用属性

一、Vue页面组成 目前的项目中&#xff0c;Vue页面都是采用组件套娃的形式&#xff0c;由一个一个的组件拼接而成整个页面。一个组件就是一个.vue文件。组件通常由template和script两部分组成&#xff1a; template部分&#xff1a;页面展示的具体元素内容&#xff0c;比如文字…

Type-c诱骗取电芯片大全

随着Type-C的普及和推广&#xff0c;目前市面上的电子设备正在慢慢淘汰micro-USB接口&#xff0c;逐渐都更新成了Type-C接口&#xff0c;micro-USB接口从2007年上市&#xff0c;已经陪伴我们走过十多个年头&#xff0c;如今也慢慢退出舞台。 今天我们评测的产品是市面上Type-C…

【OJ】最小字典序游戏

&#x1f4da;Description: 牌王和图王在玩一个游戏。 他们需要轮流移动字符串上的L&#xff0c;R指针&#xff0c;最后一位无法移动的人会输掉游戏。 给定一个字符串 s &#xff0c;起初有两个指针 L 和 R 都指向字符串的下标为k的位置(1 < k < | s |&#xff0c;|s…

CCNP350-401学习笔记(501-550题)

501、Refer to the exhibit. What is the effect of the configuration? A. The device will allow users at 192.168.0.202 to connect to vty lines 0 through 4 using the password ciscotestkey B. The device will allow only users at 192 168.0.202 to connect to vty …

Mybatis-Plus入门系列(20) -兼容多种数据库

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 文章目录前言方案分析1. 分页2. XML自定义SQL案例演示1. 配置2. 简单分页查询3. 带方言的分页查询参考前言 在我们实际开发软件产品过程中&#xff0c;数据库的类型可能不是确定的&#xff0c;也有客户…

PHP面试题

PHP相关 php7新特性 1.类型的声明 php7可以声明函数传参的类型和返回值的类型&#xff0c;比如可以用int&#xff0c;string声明参数和返回值的类型&#xff0c;如下&#xff1a; 代码&#xff1a;declare(strict_types1); function add(int $a,int $b):int{ return $a$b;…

深入浅出C++ ——手撕AVL树

文章目录前言一、AVL 树介绍二、AVL树节点的定义三、AVL树的插入四、AVL树的旋转五、AVL树的验证六、AVL树的删除七、AVL树的性能八、AVL树的实现前言 在前面的文章中介绍了map / multimap / set / multiset 容器&#xff0c;这几个容器的底层都是按照二叉搜索树来实现的。但是…

paddlepaddle目标检测

目录 1 参考链接 2 环境 3 数据集准备 4 训练 train.py 5 导出预测模型 6 预测 源码来自作者 夜雨飘零1&#xff0c;我对参考链接的代码略有修改&#xff0c;网盘地址 链接&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;ipl5 1 参考链接 博客地址 基…

Linux 实现鼠标侧边键实现代码与网页的前进、后退

前言 之前一直是使用windows进行开发&#xff0c;最近转到linux后使用VsCode编写代码。 但是不像在win环境下&#xff0c;使用鼠标侧边键可以实现代码的前向、后向跳转。浏览网页时也不行&#xff08;使用Alt Left可以后退&#xff09;。 修改键盘映射实在没有那么方便&…

文案女王彭芳如何转变为“百万发售系统”创始人?我们来探个究竟!

智多星老师 她的输出跟智多星老师几乎毫无二致&#xff0c;是抄袭还是纯属巧合呢&#xff1f; 你们问的这个问题我也想知道&#xff0c;为了了解真相&#xff0c;我让我的一个学生把那个叫“彭芳老师”的视频给我看&#xff0c;当看到她的简介时&#xff0c;我非常震惊&#…