[day5] [LeetCode] [title134,376]
134. 加油站
在一条环路上有N个加油站,其中第i个加油站有汽油gas[i] 升。
你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。
如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1。
说明:
如果题目有解,该答案即为唯一答案。
输入数组均为非空数组,且长度相同。
输入数组中的元素均为非负数。
示例 1:
输入:gas = [1,2,3,4,5] cost = [3,4,5,1,2]
输出: 3
解释: 从 3 号加油站(索引为 3 处)出发,可获得 4 升汽油。此时油箱有 = 0 + 4 = 4 升汽油开往 4 号加油站,此时油箱有 4 - 1 + 5 = 8 升汽油开往 0 号加油站,此时油箱有 8 - 2 + 1 = 7 升汽油开往 1 号加油站,此时油箱有 7 - 3 + 2 = 6 升汽油开往 2 号加油站,此时油箱有 6 - 4 + 3 = 5 升汽油开往 3 号加油站,你需要消耗 5 升汽油,正好足够你返回到 3 号加油站。因此,3 可为起始索引。
示例 2:
输入:gas = [2,3,4] cost = [3,4,3]
输出: -1
解释: 你不能从 0 号或 1 号加油站出发,因为没有足够的汽油可以让你行驶到下一个加油站。我们从 2 号加油站出发,可以获得 4 升汽油。 此时油箱有 = 0 + 4 = 4 升汽油开往 0 号加油站,此时油箱有 4 - 3 + 2 = 3 升汽油开往 1 号加油站,此时油箱有 3 - 3 + 3 = 3 升汽油你无法返回 2 号加油站,因为返程需要消耗 4 升汽油,但是你的油箱只有 3 升汽油。因此,无论怎样,你都不可能绕环路行驶一周。
加油站收获:
这一题又吃了审题的亏,这个路是环路,就是它的方向只能是一个方向,只要确定起点,然后沿着当前方向绕一周就行了,再就是我审题不认真,把要求的起点当作了整个行驶下来路程了。以下就是我写的错误的代码,虽说错误,但是有多多少少让我学会了递归调用。当作经验把它记录下来。
错误的程序376. 摆动序列
如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为摆动序列。第一个差(如果存在的话)可能是正数或负数。少于两个元素的序列也是摆动序列。
例如,[1,7,4,9,2,5]是一个摆动序列,因为差值(6,-3,5,-7,3)是正负交替出现的。相反,[1,4,7,2,5]和[1,7,4,5,5]不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。
给定一个整数序列,返回作为摆动序列的最长子序列的长度。 通过从原始序列中删除一些(也可以不删除)元素来获得子序列,剩下的元素保持其原始顺序。
示例:
输入: [1,7,4,9,2,5]
输出: 6
解释: 整个序列就是一个摆动序列。
输入: [1,17,5,10,13,15,10,5,16,8]
输出: 7
解释: 它的几个子序列满足摆动序列。其中一个是[1,17,10,13,10,16,8]。
输入: [1,2,3,4,5,6,7,8,9]
输出: 2
进阶:
你能否用 O(n) 时间复杂度完成此题?
超时的程序(错误)
程序超时这个程序不仅超时,而且也是个错误的程序。
造成超时的原因是while循环里面没有叠加的变量,导致程序陷入死循环,造成超时
为什么会错呢,因为删除的序列不仅是开头和结尾的,还有中间的,再就是这个题目所要求的是摆动序列最长子序列的长度
正确的程序
Part 1 Part 2时间复杂度
时间复杂度收获:
1. nums.reverse() 这个函数返回值为null,主要作用是将nums中的元素反转,要调用反转后的list,直接输入nums就可以直接使用
2.reversed(seq)
参数 seq -- 要转换的序列,可以是 tuple, string, list 或 range。
返回值 返回一个反转的迭代器。
3.浅拷贝,深拷贝,赋值和传地址
alist = [1,2,3,4,5]
c=copy.copy(alist) 浅拷贝
d=copy.deepcopy(alist) 深拷贝
temp = alist 传地址
归纳:
(1)直接赋值,只是传递对象的引用,原始列表改变,被赋值的temp也会做相同的改变
(2)copy浅拷贝,没有拷贝子对象,所以原始数据改变,子对象会改变
(3)深拷贝,包含对象里面的自对象的拷贝,所以原始对象的改变不会造成深拷贝里 任何子元素的改变
可以参考这个博主(毛豆)写的 https://www.cnblogs.com/xueli/p/4952063.html
4. 此题要求最长子序列,则需要从两个方面来比较,一个是从列表的头到尾开始遍历,另外一个从列表的尾到头开始遍历,取最长的子序列,即得到答案
5. for i in range(len(nums)) ,由于在循环中,我需要删除元素,所以,i的值是需要在循环途中更改的,len(nums)也是动态的。但是这个for循环中的i值是不能在循环途中更改的,所以,用while替换。简而言之,静态循环用for ,动态循环用while.
6.此题的效率不高,可以考虑是否有别的更优的方案解决这个问题。