【日常】2022年4月25日 - 2022年5月1日

本文探讨了两种高效的算法实现:一种是优化合并多个升序链表的方法,通过使用最小堆来降低时间复杂度至O(n log n);另一种是利用中心拓展策略解决回文子串问题,将时间复杂度优化到O(n^2)。这些优化对于提高算法效率至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

23. 合并K个升序链表(Hard

# 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]:
        # 合并两个升序链表很容易,设置2个指针往后移动就行
        # 但是,现在我们不知道应该设置几个指针,可以设置一个指针数组
        pointers = []
        for p in lists:
            pointers.append(p)
        
        dummy = ListNode(-1)
        cur = dummy

        empty = set()
        while len(empty) != len(lists):
            # 找出当前所有指针指向的元素的最小值
            min_index = -1
            min_num = float('inf')

            for i in range(len(pointers)):
                if not pointers[i]: 
                    empty.add(i)
                    continue 
                if pointers[i].val < min_num:
                    min_index = i
                    min_num = pointers[i].val
            
            if min_index != -1:
                cur.next = ListNode(pointers[min_index].val)
                cur = cur.next
                # 将最小的指针往后移动
                pointers[min_index] = pointers[min_index].next
        
        return dummy.next
# 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]:
        heap = []
        # 遍历所有链表,将元素存成一个堆 O(n) n为总结点个数
        for i in range(len(lists)):
            node = lists[i]
            while node:
                heapq.heappush(heap, node.val)
                node = node.next
        
        # 依次取出节点值 O(nlogn)
        dummy = ListNode(-1)
        cur = dummy
        while heap:
            num = heapq.heappop(heap)
            cur.next = ListNode(num)
            cur = cur.next
        
        return dummy.next

647. 回文子串

解法1:暴力,枚举出所有字串,在判断每一个字串是不是回文的。

class Solution:
    def countSubstrings(self, s: str) -> int:
        res = 0
        n = len(s)
        for i in range(n):
            for j in range(i, n):
                if s[i:j+1] == s[i:j+1][::-1]:
                    res += 1
        
        return res

算法复杂度, O ( n 3 ) O(n^3) O(n3)。因为最里面还需要对字符串进行取反

解法2:中心拓展
枚举所有的回文子串的中心,这里要注意到,回文子串长度是奇数的话,中心是一个位置;长度为偶数的话,中心是两个位置。这两种情况都需要考虑到。每遍历一次,让左右指针(奇数的话两个指针初始状态指向同一个位置,偶数的话指向两个相邻的位置)进行移动(如果两个指针指向的元素相等),如果不等,就可以终止内层循环了。

class Solution:
    def countSubstrings(self, s: str) -> int:
        res = 0
        n = len(s)

        i = j = 0
        while i < (2*n-1):
            l, r = i // 2, i // 2 + i % 2
            while l >= 0 and r < n and s[l] == s[r]:
                l -= 1
                r += 1
                res += 1
            i += 1
        return res

复杂度 O ( n 2 ) O(n^2) O(n2)。只需要两层循环即可。

后面还有几题没有记录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值