Leetcode 【739、946、973】

题目描述:【Stack】739. Daily Temperatures
解题思路:

这道题是给一个温度列表,重新生成一个列表:对应位置是需要再等待多久温度才会升高超过该日的天数。

看了下数据范围,直接暴力肯定不行。再读一下题目想到可以使用递减栈(栈中存储递减的温度)来解决。为了记录每个温度的位置,还要在栈中存储对应温度的索引,即(索引,温度)。做法如下:

如果栈中有温度,且当前温度比栈中温度大,就出栈,当前索引减去出栈温度的索引就是对应的结果。每次比较完后,将当前温度入栈。

举个例子:T = [73, 74, 75, 71, 69, 72, 76, 73],栈的变化是 [(0, 73)] -> [(1, 74)] (74 > 73,73 出栈,ans[0] = 1 - 0 = 1)-> [(2, 75)] (75 > 74,74 出栈,ans[1] = 2 - 1 = 1)-> [(2, 75), (3, 71)] (71 < 75,不执行操作)-> [(2, 75), (3, 71), (4, 69)] (69 < 71,不执行操作)-> [(2, 75), (5, 72)] (72 > 69 和 71,69 和 71 依次出栈,ans[4] = 5 - 4 = 1, ans[3] = 5 - 3 = 2)-> [(6, 76)](76 > 72 和 75,72 和 75 依次出栈,ans[5] = 6 - 5 = 1, ans[2] = 6 - 2 = 4)-> [(6, 76), (7, 73)](73 < 76,不执行操作),结束。最后,栈中剩下的一定是个递减序列,全部为 0 即可。可以得到结果 ans = [1, 1, 4, 2, 1, 1, 0, 0]。

Python3 实现:
class Solution:
    def dailyTemperatures(self, T: List[int]) -> List[int]:
        stack = []
        ans = [0] * len(T)
        for i in range(len(T)):
            while len(stack) > 0 and T[i] > stack[-1][1]:  # 当前数比栈顶数大,出栈
                ind, _ = stack.pop()
                ans[ind] = i - ind
            stack.append((i, T[i]))
        return ans

题目描述:【Two Pointers】946. Validate Stack Sequences
解题思路:

这道题是给 pushed 和 popped 两个序列,判断是否 pushed 序列能够通过 pop 操作得到 popped 序列。

只需要使用两个指针 i、j 分别指向 pushed 和 popped,如果 pushed[i] != popped[j],i 往后移,直到找到第一个能够和 popped 序列对应的 pop 位置。然后,pushed 删除当前元素 pushed[i],同时 i 向前移动一位,代表出栈。j 向后移动一位,判断下一个 pop 的位置。

注意到如果刚开始就相同,如 pushed = [0, 1, 2],popped = [0, 2, 1],删除 pushed[0] 后索引 i 会变成 -1,因此还要加一个判断,就是如果 i < 0,让 i = 0 即可。

Python3 实现:
class Solution:
    def validateStackSequences(self, pushed: List[int], popped: List[int]) -> bool:
        i = j = 0
        while i < len(pushed) and j < len(popped):
            if pushed[i] != popped[j]:
                i += 1
            else:
                del pushed[i]
                i -= 1
                if i < 0: i = 0  # pushed和popped起始位置对应,del后i会变为-1
                j += 1
        # 满足题意的一定是最后pushed为空且j到达了popped的末尾
        return True if len(pushed) == 0 and j == len(popped) else False

print(Solution().validateStackSequences([0,1,2], [0,2,1]))  # True

题目描述:【Sort、Heap】973. K Closest Points to Origin
解题思路:

这道题是给一些坐标,求距离原点 (0, 0) 前 K 小距离(欧氏距离)的那些坐标。

思路很直接:先求出所有点距离原点的距离(O(n) 的复杂度),然后按照距离从小到大排序(O(nlogn) 的复杂度),最后输出前 K 个结果。总的时间复杂度为 O(nlogn)。

为了在排序距离时记录原来坐标的位置,可以以(距离,索引)的形式一起排序,输出前 K 个结果时,就可以根据索引找到原来坐标的位置。实现代码如代码1所示:

Python3 实现:

代码1:

class Solution:
    def kClosest(self, points: List[List[int]], K: int) -> List[List[int]]:
        dis = []
        ans = []
        for i, point in enumerate(points):
            dis.append((point[0]*point[0]+point[1]*point[1], i))  # (距离,索引)
        dis.sort()
        for i in range(K):
            ans.append(points[dis[i][1]])
        return ans

实际上,sorted 函数可以通过指定 key 来直接定义排序规则,就不需要像代码1那样算距离的时候还要保存索引了。实现代码如代码2所示:

代码2:

class Solution:
    def kClosest(self, points: List[List[int]], K: int) -> List[List[int]]:
        return sorted(points, key = lambda x: x[0]**2 + x[1]**2)[:K]

取前 K 小(或 K 大)个元素可以使用最小优先队列(或最大优先队列)。我们知道,优先队列不是真正的队列,它只是维护的一个堆,优先队列每次输出的是最大(或最小)的堆顶元素,而不是遵循先入先出。输出元素的时间复杂度为 O(logn)。

可以使用 Python 中的 heapq 组件,通过调用 heapq.nsmallest(K, points, key = lambda x: x[0]**2 + x[1]**2) (取最大的 K 个元素对应函数是 heapq.nlargest(...))解决。

但是由于建堆的过程是 O(nlogn) 级别的,因此总时间复杂度还是 O(nlogn)。实现代码如代码3所示:

代码3:

import heapq
class Solution:
    def kClosest(self, points: List[List[int]], K: int) -> List[List[int]]:
        return heapq.nsmallest(K, points, key = lambda x: x[0]**2 + x[1]**2)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容