每日一练 — 2022.02.18


一,天际线问题

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<=2311
  • 1 < = h e i g h t i < = 2 31 − 1 1 <= heighti <= 2^{31} - 1 1<=heighti<=2311
  • 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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梁辰兴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值