文章目录
一,天际线问题
1,程序简介
城市的天际线是从远处观看该城市中所有建筑物形成的轮廓的外部轮廓。给你所有建筑物的位置和高度,请返回由这些建筑物形成的 天际线 。
每个建筑物的几何信息由数组 buildings 表示,其中三元组 buildings[i] = [lefti, righti, heighti] 表示:
- lefti 是第 i 座建筑物左边缘的 x 坐标。
- righti 是第 i 座建筑物右边缘的 x 坐标。
- heighti 是第 i 座建筑物的高度。
天际线 应该表示为由 “关键点” 组成的列表,格式 [[x1,y1],[x2,y2],…] ,并按 x 坐标 进行 排序 。关键点是水平线段的左端点。列表中最后一个点是最右侧建筑物的终点,y 坐标始终为 0 ,仅用于标记天际线的终点。此外,任何两个相邻建筑物之间的地面都应被视为天际线轮廓的一部分。
注意:输出天际线中不得有连续的相同高度的水平线。例如 […[2 3], [4 5], [7 5], [11 5], [12 7]…] 是不正确的答案;三条高度为 5 的线应该在最终输出中合并为一个:[…[2 3], [4 5], [12 7], …]
示例 1:
- 输入:buildings = [[2,9,10],[3,7,15],[5,12,12],[15,20,10],[19,24,8]]
- 输出:[[2,10],[3,15],[7,12],[12,0],[15,10],[20,8],[24,0]]
- 解释:
图 A 显示输入的所有建筑物的位置和高度,
图 B 显示由这些建筑物形成的天际线。图 B 中的红点表示输出列表中的关键点。
示例 2:
- 输入:buildings = [[0,2,3],[2,5,3]]
- 输出:[[0,3],[5,0]]
提示:
- 1 < = b u i l d i n g s . l e n g t h < = 1 0 4 1 <= buildings.length <= 10^4 1<=buildings.length<=104
- 0 < = l e f t i < r i g h t i < = 2 31 − 1 0 <= lefti < righti <= 2^{31} - 1 0<=lefti<righti<=231−1
- 1 < = h e i g h t i < = 2 31 − 1 1 <= heighti <= 2^{31} - 1 1<=heighti<=231−1
- buildings 按 lefti 非递减排序
2,程序代码
# -*- coding: utf-8 -*-
"""
Created on Thu Feb 17 08:22:23 2022
Function: 天际线问题
@author: 小梁aixj
"""
import heapq
class Solution:
def getSkyline(self, buildings: List[List[int]]) -> List[List[int]]:
right_heap = []
height_lst = []
ans = []
for building in buildings:
left, right, height = building
while right_heap and right_heap[0][0] < left:
old_highest = height_lst[-1]
last_right, last_height = heapq.heappop(right_heap)
height_lst.pop(bisect.bisect_left(height_lst, last_height))
new_highest = height_lst[-1] if height_lst else 0
if new_highest != old_highest:
if ans and ans[-1][0] == last_right:
ans.pop()
ans.append([last_right, new_highest])
old_highest = height_lst[-1] if height_lst else 0
bisect.insort_left(height_lst, height)
heapq.heappush(right_heap, (right, height))
new_highest = height_lst[-1]
if new_highest != old_highest:
if ans and ans[-1][0] == left:
ans.pop()
ans.append([left, new_highest])
while right_heap:
old_highest = height_lst[-1]
last_right, last_height = heapq.heappop(right_heap)
height_lst.pop(bisect.bisect_left(height_lst, last_height))
new_highest = height_lst[-1] if height_lst else 0
if new_highest != old_highest:
if ans and ans[-1][0] == last_right:
ans.pop()
ans.append([last_right, new_highest])
return ans
二,多数元素
1,程序简介
给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
- 输入:[3,2,3]
- 输出:3
示例 2:
- 输入:[2,2,1,1,1,2,2]
- 输出:2
进阶:
- 尝试设计时间复杂度为 O(n)、空间复杂度为 O(1) 的算法解决此问题。
2,程序代码
# -*- coding: utf-8 -*-
"""
Created on Thu Feb 17 08:22:50 2022
Function: 多数元素
@author: 小梁aixj
"""
class Solution:
def majorityElement(self, nums: List[int]) -> int:
count, candi = 0, 0
for i in nums:
if i == candi:
count += 1
else:
if count == 0:
candi = i
count = 1
else:
count -= 1
return candi
三,回文对
1,程序简介
给定一组 互不相同 的单词, 找出所有 不同 的索引对 (i, j),使得列表中的两个单词, words[i] + words[j] ,可拼接成回文串。
示例 1:
- 输入:words = [“abcd”,“dcba”,“lls”,“s”,“sssll”]
- 输出:[[0,1],[1,0],[3,2],[2,4]]
- 解释:可拼接成的回文串为
[“dcbaabcd”,“abcddcba”,“slls”,“llssssll”]
示例 2:
- 输入:words = [“bat”,“tab”,“cat”]
- 输出:[[0,1],[1,0]]
- 解释:可拼接成的回文串为
[“battab”,“tabbat”]
示例 3:
- 输入:words = [“a”,""]
- 输出:[[0,1],[1,0]]
提示:
- 1 <= words.length <= 5000
- 0 <= words[i].length <= 300
- words[i] 由小写英文字母组成
2,程序代码
# -*- coding: utf-8 -*-
"""
Created on Thu Feb 17 08:24:21 2022
Function: 回文对
@author: 小梁aixj
"""
class Solution:
def palindromePairs(self, words: List[str]) -> List[List[int]]:
def is_palindrome(str, start, end):
"""检查子串是否是回文串
"""
part_word = str[start : end + 1]
return part_word == part_word[::-1]
def find_reversed_word(str, start, end):
"""查找子串是否在哈希表中
Return:
不在哈希表中,返回 -1
否则返回对应的索引
"""
part_word = str[start : end + 1]
ret = hash_map.get(part_word, -1)
return ret
hash_map = {}
for i in range(len(words)):
word = words[i][::-1]
hash_map[word] = i
res = []
for i in range(len(words)):
word = words[i]
word_len = len(word)
if is_palindrome(word, 0, word_len - 1) and "" in hash_map and word != "":
res.append([hash_map.get(""), i])
for j in range(word_len):
if is_palindrome(word, j, word_len - 1):
left_part_index = find_reversed_word(word, 0, j - 1)
if left_part_index != -1 and left_part_index != i:
res.append([i, left_part_index])
if is_palindrome(word, 0, j - 1):
right_part_index = find_reversed_word(word, j, word_len - 1)
if right_part_index != -1 and right_part_index != i:
res.append([right_part_index, i])
return res