每日温度(LeetCode Medium难度算法题)题解

LeetCode 题号739中等难度 每日温度

题目描述:

根据每日 气温 列表,请重新生成一个列表,对应位置的输入是你需要再等待多久温度才会升高超过该日的天数。如果之后都不会升高,请在该位置用 0 来代替。

例如,给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]。

提示:气温 列表长度的范围是 [1, 30000]。每个气温的值的均为华氏度,都是在 [30, 100] 范围内的整数。

虽说这是一个中等难度的题目,但看完题目后会发现其实要做出来其实不困难,甚至可以说有点简单(单纯的为了AC)

很简单,题目要求就是给一个数组,让你返回一个数组,新数组对应位置表示的是题目给的数组对应位置往后找第一个值比其大的位置距离,如果没有则为0;

直接简单循环遍历就可以通过了。

 1 class Solution {
 2     public int[] dailyTemperatures(int[] T) {
 3         int[] ans = new int[T.length];
 4         for(int i = 0 ; i < T.length-1;i++){
 5             ans[i] = 0 ;
 6             for(int j = i+1;j<T.length;j++){
 7                 if(T[j]>T[i]){
 8                     ans[i] = j-i;
 9                     break;
10                 }
11             }
12         }
13         return ans;
14     }
15 }

这样子就可以ac了,但是效率呢?

先上ac后截图:

223ms- -,吓死个人了。仅仅30%多而已。

在我看来,刷题第一个目标是为了ac,第二个目标是优化。

本人也是个渣渣,也不会优化- -。但是leetcode上有大牛- -。

多说无益直接上大牛代码:

 1 class Solution {
 2    public int[] dailyTemperatures(int[] T) {
 3     int length = T.length;
 4     int[] result = new int[length];
 5
 6     //从右向左遍历
 7     for (int i = length - 2; i >= 0; i--) {
 8         // j+= result[j]是利用已经有的结果进行跳跃
 9         for (int j = i + 1; j < length; j+= result[j]) {
10             if (T[j] > T[i]) {
11                 result[i] = j - i;
12                 break;
13             } else if (result[j] == 0) { //遇到0表示后面不会有更大的值,那当然当前值就应该也为0
14                 result[i] = 0;
15                 break;
16             }
17         }
18     }
19
20     return result;
21 }
22 }

看起来好像没有什么变化好像只是菜鸡小老弟我多了个几行- -。

但是我们看看大佬代码ac后的截图

4ms,和菜鸡我的200多ms 比起来我只是个弟中弟。

话不多说来分析一下大佬的精辟思想。

直接看核心代码:

 1 //从右向左遍历
 2     for (int i = length - 2; i >= 0; i--) {
 3         // j+= result[j]是利用已经有的结果进行跳跃
 4         for (int j = i + 1; j < length; j+= result[j]) {
 5             if (T[j] > T[i]) {
 6                 result[i] = j - i;
 7                 break;
 8             } else if (result[j] == 0) { //遇到0表示后面不会有更大的值,那当然当前值就应该也为0
 9                 result[i] = 0;
10                 break;
11             }
12         }
13     }
14
15 作者:pulsaryu
16 链接:https://leetcode-cn.com/problems/daily-temperatures/solution/jie-ti-si-lu-by-pulsaryu/
17 来源:力扣(LeetCode)
18 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

大佬习惯——代码写注释。

可能有的人看完还不是很懂我们具体再分析一下。

首先,我们肯定要遍历每一个数组元素的值的。那我们优化的点只能是在比较的过程。

回想题目要求,我们是要从当前位置往后面找第一个比该位置值大的位置与他的距离(其实就是下标的差);

然后把这个距离存进返回的数组对应的位置下标。

我们正常想都是从前往后遍历。但是这题我们每次遍历都得往后找。那我们可以尝试着从后往前即从右往左啦。

再这个基础上,再往后找。

这样子的好处是我们往后找的时候,后方的位置都是已经计算好的。

如果我们的是从前往后遍历,那我们比较永远只能一个位置一个位置都比较找到第一个值大的位置则为止继续找下一个位置。

如果我们已经算好后方的位置呢?

看下大佬的图文:

71的位置对应值2,表明71的后面的的第二个元素就是第一个比71大的位置。

这样子我们就可以跳跃。我们求75位置。往后找的时候,如果后方的比当前位置小,那们我们没有必要j++这样子一个一个看,我们可以直接

根据后方元素的值即result[j]跳跃,我们不用j++;我们可以直接j = j+ result[j];再与75比较如果比75大则返回索引差。

如果后方位置的值 比当前位置小并且result[j]==0代表什么呢?就是代表 j 位置 后方的都没有j 位置的大。而当前位置又比J位置的大。那当前位置

往后找也找不出一个比其大的位置  所以 直接result[i] = 0;

每一次计算出当前位置的值后我们就直接break 掉内层循环  然后接着遍历前一个元素即可.

其实这种跳跃思想有点像 字符串模式匹配用到的KMP算法next数组的思想。

如果不知道KMP是什么的可以点下方连接学习

https://blog.csdn.net/sinat_37537673/article/details/73331135

本人只是个普通二本在读大二的菜鸡,只是个搬运工,不喜勿喷- -。

原文地址:https://www.cnblogs.com/vibe/p/11725533.html

时间: 2024-10-08 16:04:24

每日温度(LeetCode Medium难度算法题)题解的相关文章

Leetcode medium难度顺序题解

被迫重操旧业(?) 再不刷题面试就真要翻车了.... 好在medium题难度还比较水,幸亏它不考什么神DP或数据结构或blabla不然我还面个锤子(x) 但是现场写代码还不准出错ATP顶8住啊所以还是练练手感叭.... 就,按顺序随便做几个.点中等难度然后按题号排序这样. 2. 两数相加 高精度但是用单向链表. 一开始ATP写的很麻烦,基本思路是先把两个数字重叠的部分相加,然后再单独处理较长的数字多出来的那部分,然后再处理进位这样.一共三个while循环. 但是后来发现好像直接改一下判断条件,如

leetcode sum相关算法题

1. Two Sum(https://oj.leetcode.com/problems/two-sum/) 解题思路: 解法一: 暴力,O(n2)时间复杂度,TLE 解法二:利用hash, 记录下数组中每个值对应的下标,再遍历一遍数组,通过查看target-num[i]的值是否在map中来确定另一个数值.时间复杂度O(n) 解法三:对num数组排序,O(nlog(n)), 然后左右夹逼O(n). 但这道题要求记录下标,故这个方法行不通. python代码如下: 1 def twoSum(self

【leetcode】经典算法题-Counting Bits

题目描述: 给定一个数字n,统计0-n之间的数字二进制的1的个数,并用数组输出 例子: For num = 5 you should return [0,1,1,2,1,2]. 要求: 算法复杂复o(n) 空间复杂度o(n) 原文描述: Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate the number of 1's in their binary r

常见算法题合辑(一)

这一章的内容,有些之前已经在微信公众号中将详细的思路及步骤汇总过,有些之后可能会再找时间对其进行分析,这里只将最终实现罗列出来,难易程度不分先后,算法复杂度不保证是最优,留给大家空间自行思考,当然,本章用的是C#语言进行编码,大家可以使用自己熟悉的语言将这些算法实现一遍哦~ 如果你有什么有趣的算法题或者没能解决的算法题,也可以留言给小编,让我们一起玩转算法~ 1. 冒泡排序 这个算是所有算法中最为简单的了,实现方法如下: 2. 插入排序 从排序算法来看,这个算法也是属于比较简单的了,实现方法如下

五分钟学会一个高难度算法:希尔排序

前言 由于LeetCode上的算法题很多涉及到一些基础的数据结构,为了更好的理解后续更新的一些复杂题目的动画,推出一个新系列 ---<图解数据结构>,主要使用动画来描述常见的数据结构和算法.本系列包括十大排序.堆.队列.树.并查集.图等等大概几十篇. 希尔排序 希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本.但希尔排序是非稳定排序算法.希尔排序是基于插入排序的以下两点性质而提出改进方法的: 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率: 但插入排序

LeetCode:每日温度【739】

LeetCode:每日温度[739] 题目描述 根据每日 气温 列表,请重新生成一个列表,对应位置的输入是你需要再等待多久温度才会升高的天数.如果之后都不会升高,请输入 0 来代替. 例如,给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]. 提示:气温 列表长度的范围是 [1, 30000].每个气温的值的都是 [30, 100] 范围内的整数. 题目分析 说实话,看到这

Leetcode 算法题--ReverseWordsInString

翻转字符串,想到什么写什么...我的做法是先trim掉空格,然后从字符串尾部开始扫描,遇到空格则认为一个单词结束,然后copy这个单词.需要注意的地方在于当扫描到最后一个单词的第一个字母时(譬如the sky is blue的t字母),注意单词长度的自增逻辑. 网上还有人的做法是反转整个字符串,然后逐个翻转单词. 1 package edu.hust.sse.Problems; 2 3 //Given s = "the sky is blue", 4 //return "bl

leetcode中关于树的dfs算法题

Validate Binary Search Tree Recover Binary Search Tree Symmetric Tree Same Tree Maximum Depth of Binary Tree Construct Binary Tree from Preorder and Inorder Traversal Construct Binary Tree from Inorder and Postorder Traversal Convert Sorted Array to

经典算法题每日演练——第十六题 Kruskal算法

原文:经典算法题每日演练--第十六题 Kruskal算法 这篇我们看看第二种生成树的Kruskal算法,这个算法的魅力在于我们可以打一下算法和数据结构的组合拳,很有意思的. 一:思想 若存在M={0,1,2,3,4,5}这样6个节点,我们知道Prim算法构建生成树是从”顶点”这个角度来思考的,然后采用“贪心思想” 来一步步扩大化,最后形成整体最优解,而Kruskal算法有点意思,它是站在”边“这个角度在思考的,首先我有两个集合. 1. 顶点集合(vertexs): 比如M集合中的每个元素都可以认