前文
继上一篇:leetcode题1/26/27/35/53/66/88/118/119已过去了一周,这次接着分享数组前300的easy题,话不多说,直接上题。
121. Best Time to Buy and Sell Stock
class Solution:
"""
卡登算法,维护当前的最小值和截止目前的利润最大值,这样随着遍历就能找到截止目前的最大值
Runtime: 40 ms, faster than 99.90% of Python3 online submissions for Best Time to Buy and Sell Stock.
"""
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
min_profit = float("inf")
tonow_max_profit = 0
for i in prices:
if i < min_profit:
min_profit = i
if i-min_profit > tonow_max_profit:
tonow_max_profit = i - min_profit
return tonow_max_profit
class Solution:
"""
正常思路的优化,正常思路就是双重循环,代码做了2个优化,第1个是在第二次while的时候增加prices[i]-prices[j]>0的判断,
可在当找到更小值时直接结束循环;第2个优化是在第一个while的if下i=j,这样虽然是双重循环,但因为i=j的骚操作,实际上也变成了
单层循环。
Runtime: 40 ms, faster than 99.90% of Python3 online submissions for Best Time to Buy and Sell Stock.
"""
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
i = j = maxjsum = 0
n = len(prices)
while i < n-1:
if prices[i] < prices[i+1]:
j = i + 1
while j < n and prices[j]-prices[i] > 0:
if prices[j] - prices[i] > 0:
maxjsum = max(maxjsum, prices[j]-prices[i])
j += 1
i = j
else:
i += 1
return maxjsum
122. Best Time to Buy and Sell Stock II
class Solution:
"""
这道题就是典型的贪心算法:即每次都取当前的最佳结果
对应到题目就是:一有利益就卖出,最后累计的结果即是最终结果
因为不能当天买入和卖出,所以每买进一个,如果有收益就卖出,这样才能不断地买进卖出
Runtime: 40 ms, faster than 99.86% of Python3 online submissions for Best Time to Buy and Sell Stock II.
"""
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
res = 0
for index,value in enumerate(prices[1:],1):
if value > prices[index-1]:
res += value - prices[index-1]
return res
167. Two Sum II - Input array is sorted
class MySolution:
"""
这道题采用的解法和第一题Two Sum是一模一样的,唯一不同的是题目要求从1开始计数,所以在返回值上各加了一
Runtime: 36 ms, faster than 99.77% of Python3 online submissions for Two Sum II - Input array is sorted.
"""
def twoSum(self, numbers, target):
"""
:type numbers: List[int]
:type target: int
:rtype: List[int]
"""
res_dict = {}
for index,value in enumerate(numbers):
sub = target - value
if sub in res_dict:
return [res_dict[sub]+1, index+1]
else:
res_dict[value] = index
class Solution:
"""
讨论区看到的Two-pointer的解法,看起来很棒,因为是有序,所以计算第一个和最后一个的和,如果>target则说明后一个数大了,那就往前推移;
如果小了,说明前一个数小了,那就往后推移;直到找到那个值;当然也有二分法,但我觉得这道题没必要用二分法来做。
Runtime: 36 ms, faster than 99.77% of Python3 online submissions for Two Sum II - Input array is sorted.
"""
def twoSum(self, numbers, target):
"""
:type numbers: List[int]
:type target: int
:rtype: List[int]
"""
l, r = 0, len(numbers)-1
while l < r:
s = numbers[l] + numbers[r]
if s == target:
return [l+1, r+1]
elif s < target:
l += 1
else:
r -= 1
169. Majority Element
class MySolution:
"""
先投机取巧用python的计数器counter来做,通过most_common去到值最多的1个[()],然后通过索引定位到元素
Runtime: 48 ms, faster than 94.33% of Python3 online submissions for Majority Element.
"""
def majorityElement(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
from collections import Counter
c = Counter(nums)
return c.most_common(1)[0][0]
class MySolution2:
"""
这是除了Counter外自己想的比较笨拙的方法,通过字典存在就给值+1的方法来捕获,然后判断值是否大于n/2就ok了
Runtime: 60 ms, faster than 59.69% of Python3 online submissions for Majority Element.
"""
def majorityElement(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if len(nums) == 1:
return nums[0]
res_dict = {}
for i in nums:
if i in res_dict:
res_dict[i] += 1
if res_dict[i] > len(nums)//2:
return i
else:
res_dict[i] = 1
189. Rotate Array
class MySolution:
"""
我的解决方法就是通常想到的,通过循环,每一次把最后的数插入到最前方。当然效率也是很慢的,达到132ms
Runtime: 132 ms, faster than 22.71% of Python3 online submissions for Rotate Array.
"""
def rotate(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: void Do not return anything, modify nums in-place instead.
"""
index = -1
while index >= -k:
nums.insert(0, nums.pop())
index -= 1
class Solution:
"""
讨论区看的答案,还是被惊艳到了,直接对nums进行三次颠倒就行了,相当于从宏观来考虑
不过需要补上k取余,因为会给出k的值大于nums的length情况
Runtime: 44 ms, faster than 100.00% of Python3 online submissions for Rotate Array.
"""
def rotate(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: void Do not return anything, modify nums in-place instead.
"""
k = k % len(nums)
nums[:-k] = nums[:-k][::-1]
nums[-k:] = nums[-k:][::-1]
nums[:] = nums[::-1]
class Solution2:
"""
可以在上述方法再做优化,直接取一半的数值
"""
def rotate(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: void Do not return anything, modify nums in-place instead.
"""
k = k % len(nums)
nums[:] = nums[n-k:] + nums[:n-k]
217. Contains Duplicate
class MySolution:
"""
我的解法很简单,还是从字典入手,如果发现当前值存在字典,则说明超过两次;当然速度就堪忧了。
Runtime: 48 ms, faster than 80.28% of Python3 online submissions for Contains Duplicate.
"""
def containsDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
res_dict = {}
for i in nums:
if i not in res_dict:
res_dict[i] = 0
else:
return True
return False
class MySolution2:
"""
看到数数就想到python的计数器,我的第二种解法就是利用Counter和它most_common来做
Runtime: 48 ms, faster than 80.28% of Python3 online submissions for Contains Duplicate.
"""
def containsDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
from collections import Counter
if not len(nums):
return False
c = Counter(nums)
res = c.most_common(1)[0][1]
return res != 1
class Solution:
"""
讨论区的一向精简,直接通过set来完成,不得不说从列表中判断数量时set非常好用
Runtime: 44 ms, faster than 98.12% of Python3 online submissions for Contains Duplicate.
"""
def containsDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
return len(set(nums)) != len(nums)
219. Contains Duplicate II
class MySolution:
"""
我的解法还是利用字典来做,要注意的是当第一轮找到的两个相同的数距离大于k时,要用第二个数的index重置第一个数,继续往下遍历
Runtime: 48 ms, faster than 88.89% of Python3 online submissions for Contains Duplicate II.
"""
def containsNearbyDuplicate(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: bool
"""
res_dict = {}
for index,value in enumerate(nums):
if value not in res_dict:
res_dict[value] = index
else:
res = index - res_dict[value]
if res <= k:
return True
else:
res_dict[value] = index
return False
class Solution:
"""
看到讨论区的字典解法比我的简单点,不过原理是一样的,mark一下,不过连runtime都比我的好
Runtime: 44 ms, faster than 97.62% of Python3 online submissions for Contains Duplicate II.
"""
def containsNearbyDuplicate(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: bool
"""
dic = {}
for i, v in enumerate(nums):
if v in dic and i - dic[v] <= k:
return True
dic[v] = i
return False
268. Missing Number
class MySolution:
"""
用python的set差集来做,但效率很低
Runtime: 52 ms, faster than 45.33% of Python3 online submissions for Missing Number.
"""
def missingNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
n = len(nums) + 1
res_list = list(range(n))
res = set(res_list) - set(nums)
return list(res)[0]
class Solution:
"""
讨论区果然还是大神多,用求和的方法轻松拿到答案
Runtime: 40 ms, faster than 100.00% of Python3 online submissions for Missing Number.
"""
def missingNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
return sum(range(len(nums) + 1)) - sum(nums)
283. Move Zeroes
class MySolution:
"""
思路很简单,定义首尾2个数,如果首部为0就删除首部,然后尾部插入0即可
Runtime: 44 ms, faster than 100.00% of Python3 online submissions for Move Zeroes.
"""
def moveZeroes(self, nums):
"""
:type nums: List[int]
:rtype: void Do not return anything, modify nums in-place instead.
"""
start = 0
end = len(nums) - 1
while start < end:
if nums[start] == 0:
del nums[start]
nums.append(0)
end -= 1
else:
start += 1
class Solution:
"""
讨论区的一种解法直接判断是否为0,是的话就往后交换,
Runtime: 44 ms, faster than 100.00% of Python3 online submissions for Move Zeroes.
"""
def moveZeroes(self, nums):
"""
:type nums: List[int]
:rtype: void Do not return anything, modify nums in-place instead.
"""
zero = 0 # records the position of "0"
for i in range(len(nums)):
if nums[i] != 0:
nums[i], nums[zero] = nums[zero], nums[i]
zero += 1
总结
本次记录到此为止,一共九题,多谢观看~