惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Privacy & Cybersecurity Law Blog
人人都是产品经理
人人都是产品经理
The Cloudflare Blog
B
Blog RSS Feed
罗磊的独立博客
V
V2EX
V
Visual Studio Blog
博客园 - 叶小钗
W
WeLiveSecurity
小众软件
小众软件
K
Kaspersky official blog
美团技术团队
雷峰网
雷峰网
阮一峰的网络日志
阮一峰的网络日志
Martin Fowler
Martin Fowler
Recorded Future
Recorded Future
Project Zero
Project Zero
Hugging Face - Blog
Hugging Face - Blog
Engineering at Meta
Engineering at Meta
Security Latest
Security Latest
Microsoft Azure Blog
Microsoft Azure Blog
V
Vulnerabilities – Threatpost
月光博客
月光博客
博客园 - 三生石上(FineUI控件)
Help Net Security
Help Net Security
博客园 - Franky
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
F
Fortinet All Blogs
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Forbes - Security
Forbes - Security
M
MIT News - Artificial intelligence
H
Hacker News: Front Page
大猫的无限游戏
大猫的无限游戏
Vercel News
Vercel News
Spread Privacy
Spread Privacy
The Register - Security
The Register - Security
H
Hackread – Cybersecurity News, Data Breaches, AI and More
量子位
Google Online Security Blog
Google Online Security Blog
PCI Perspectives
PCI Perspectives
The Last Watchdog
The Last Watchdog
AI
AI
N
News | PayPal Newsroom
D
DataBreaches.Net
Cloudbric
Cloudbric
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 司徒正美
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
Tailwind CSS Blog

博客园 - 北叶青藤

2096. Step-By-Step Directions From a Binary Tree Node to Another Find path from root to a target node in Binary Tree When Dijkstra Algorithm Should be Use? 1188. Design Bounded Blocking Queue 1115. Print FooBar Alternately 1114. Print in Order 1242. Web Crawler Multithreaded Python Multi-threading bot ip Log Rate Limiter Same Word of HTML Labels Most Frequent Call Chain remove prefix in a words list 1102. Path With Maximum Minimum Value Property Booking Optimizer minimum number 755. Pour Water Keyword Tagging in Reviews with Overlapping Matches Retryer Function Implementation 1125. Smallest Sufficient Team Print the terrain Task scheduling problem 滑雪问题 845. Longest Mountain in Array 723. Candy Crush 1539. Kth Missing Positive Number 1650. Lowest Common Ancestor of a Binary Tree III 424. Longest Repeating Character Replacement 843. Guess the Word 551. Student Attendance Record I
Split stay
北叶青藤 · 2026-02-23 · via 博客园 - 北叶青藤

给定 n 个 hotel,每个 hotel 对应一个列表,里面的数字代表房源空闲的日期,还有一个可以请求的日期范围 [start_date, end_date]。

然后把这个区间能够 split 成连续的两段,分别能够找到两个 hotel 来满足这个对应区间,且左右不能来回 overlapping(只能 forward)。要求返回对应的 hotel 组合,且不能重复。

简单版本

 1 def find_hotel_pairs(hotels, start_date, end_date):
 2     """
 3     hotels: Dict[str, List[int]] -> { "Hotel1": [1, 2, 3], "Hotel2": [4, 5], ... }
 4     start_date: int
 5     end_date: int
 6     """
 7     # 1. 预处理:将日期列表转换为集合,提高查询效率
 8     hotel_sets = {name: set(dates) for name, dates in hotels.items()}
 9     hotel_names = list(hotels.keys())
10     results = set()
11 
12     # 定义一个辅助函数,检查酒店是否覆盖特定闭区间
13     def covers_range(hotel_name, s, e):
14         s_set = hotel_sets[hotel_name]
15         for d in range(s, e + 1):
16             if d not in s_set:
17                 return False
18         return True
19 
20     # 2. 枚举分割点 k
21     # 目标区间被分为 [start_date, k] 和 [k + 1, end_date]
22     for k in range(start_date, end_date):
23         left_part_hotels = []
24         right_part_hotels = []
25 
26         # 找出哪些酒店满足左半段,哪些满足右半段
27         for name in hotel_names:
28             if covers_range(name, start_date, k):
29                 left_part_hotels.append(name)
30             if covers_range(name, k + 1, end_date):
31                 right_part_hotels.append(name)
32 
33         # 3. 组合满足条件的酒店对
34         for h_a in left_part_hotels:
35             for h_b in right_part_hotels:
36                 # 如果要求两家酒店不能是同一家,可以加上 if h_a != h_b
37                 results.add((h_a, h_b))
38 
39     return list(results)
40 
41 # --- 测试用例 ---
42 hotels_data = {
43     "Hotel_A": [10, 11, 12],
44     "Hotel_B": [12, 13, 14, 15],
45     "Hotel_C": [10, 11],
46     "Hotel_D": [13, 14, 15]
47 }
48 
49 start, end = 10, 15
50 pairs = find_hotel_pairs(hotels_data, start, end)
51 
52 print(f"在区间 [{start}, {end}] 内满足条件的酒店组合有:")
53 for p in pairs:
54     print(f"前半段: {p[0]}, 后半段: {p[1]}")

进阶版本

 1 def find_hotel_pairs_optimized(hotels, start_date, end_date):
 2     hotel_sets = {name: set(dates) for name, dates in hotels.items()}
 3     
 4     # 记录哪些酒店能覆盖 [start_date, k]
 5     # left_reach[k] 存储所有能覆盖 start_date 到 k 的酒店名
 6     left_reach = {}
 7     # 记录哪些酒店能覆盖 [k, end_date]
 8     # right_reach[k] 存储所有能覆盖 k 到 end_date 的酒店名
 9     right_reach = {}
10 
11     total_range = range(start_date, end_date + 1)
12 
13     for name, dates_set in hotel_sets.items():
14         # 1. 从左向右检查连续性
15         for k in range(start_date, end_date):
16             # 只有当 [start_date, k] 都在集合里,该酒店才符合前半段
17             if all(d in dates_set for d in range(start_date, k + 1)):
18                 left_reach.setdefault(k, []).append(name)
19             else:
20                 break # 一旦断开,更长的区间也不可能满足
21         
22         # 2. 从右向左检查连续性
23         for k in range(end_date, start_date, -1):
24             # 只有当 [k, end_date] 都在集合里,该酒店才符合后半段
25             if all(d in dates_set for d in range(k, end_date + 1)):
26                 right_reach.setdefault(k, []).append(name)
27             else:
28                 break
29 
30     # 3. 组合结果
31     results = set()
32     # 分割点 k 是前半段的终点,k+1 是后半段的起点
33     for k in range(start_date, end_date):
34         lefts = left_reach.get(k, [])
35         rights = right_reach.get(k + 1, [])
36         
37         for h1 in lefts:
38             for h2 in rights:
39                 results.add((h1, h2))
40 
41     return list(results)