题解
思路
代码
"""
# Definition for a Node.
class Node:
def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None):
self.val = int(x)
self.next = next
self.random = random
"""
class Solution:
### 1130 哈希表(60 ms,14.2 MB)
def copyRandomList(self, head: 'Node') -> 'Node':
# 若head为空,直接返回
if not head: return
# 第一次遍历链表:构建哈希表,用于存放 '原节点:复制的新节点'
dic = {}
cur = head
while cur:
dic[cur] = Node(cur.val)
cur = cur.next
# 第二次遍历链表:构建新节点的 next 和 random 指向
cur = head
while cur:
dic[cur].next = dic.get(cur.next)
dic[cur].random = dic.get(cur.random)
cur = cur.next
return dic[head] # 返回新链表的头节点
# 方法二:拼接 + 拆分
def copyRandomList(self, head: 'Node') -> 'Node':
if not head: return
cur = head
# 1. 复制各节点,并构建拼接链表
while cur:
tmp = Node(cur.val)
tmp.next = cur.next
cur.next = tmp
cur = tmp.next
# 2. 构建各新节点的 random 指向
cur = head
while cur:
if cur.random:
cur.next.random = cur.random.next
cur = cur.next.next
# 3. 拆分两链表
cur = res = head.next
pre = head
while cur.next:
pre.next = pre.next.next
cur.next = cur.next.next
pre = pre.next
cur = cur.next
pre.next = None # 单独处理原链表尾节点
return res # 返回新链表头节点
382. 链表随机节点
import random
class Solution:
def __init__(self, head: ListNode):
self.head = head
def getRandom(self) -> int:
count = 0
reserve = 0
cur = self.head
while cur:
count += 1
rand = random.randint(1,count)
if rand == count:
reserve = cur.val
cur = cur.next
return reserve
133. (深拷贝)克隆图(M)
- 题解
- DFS
"""
# Definition for a Node.
class Node:
def __init__(self, val = 0, neighbors = None):
self.val = val
self.neighbors = neighbors if neighbors is not None else []
"""
# from typing import Optional
class Solution:
def __init__(self):
self.visited = {}
def cloneGraph(self, node):
if not node:
return node
# 如果该节点已经被访问过了,则直接从哈希表中取出对应的克隆节点返回
if node in self.visited:
return self.visited[node]
# 克隆节点,注意到为了深拷贝我们不会克隆它的邻居的列表
clone_node = Node(node.val, [])
# 哈希表存储
self.visited[node] = clone_node
# 遍历该节点的邻居并更新克隆节点的邻居列表
if node.neighbors:
clone_node.neighbors = [self.cloneGraph(n) for n in node.neighbors]
return clone_node
- BFS
398. 随机数索引
class Solution:
# 哈希表
def __init__(self, nums: List[int]):
self.pos = defaultdict(list)
for i, num in enumerate(nums):
self.pos[num].append(i)
def pick(self, target: int) -> int:
import random
return random.choice(self.pos[target])
# Your Solution object will be instantiated and called as such:
# obj = Solution(nums)
# param_1 = obj.pick(target)
-
法二(水塘抽样,写法1,推荐)
-
法二(水塘抽样,写法2)
1227. 飞机座位分配概率
- 官方题解
- 动态规划(一个错误使用动态规划的例子)
528. 按权重随机选择
class Solution:
def __init__(self, w: List[int]):
n = len(w)
self.prefix_sum = [0] * n
self.prefix_sum[0] = w[0]
# 前缀和
for i in range(1, n):
self.prefix_sum[i] = self.prefix_sum[i-1] + w[i]
# print(self.prefix_sum)
def pickIndex(self) -> int:
seed = random.randint(1, self.prefix_sum[-1])
index = bisect_left(self.prefix_sum, seed)
return index
# Your Solution object will be instantiated and called as such:
# obj = Solution(w)
# param_1 = obj.pickIndex()
class Solution:
def __init__(self, w: List[int]):
self.w = w
self.maxv = sum(w)
def pickIndex(self) -> int:
x = random.randint(1,self.maxv)
for i in range(0,len(self.w)):
x -= self.w[i]
if x <= 0:
return i
# Your Solution object will be instantiated and called as such:
# obj = Solution(w)
# param_1 = obj.pickIndex()