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)。只需要两层循环即可。
后面还有几题没有记录