第8周作业 #高级编程技术
#213. House Robber II
题目来源
https://leetcode.com/problems/house-robber-ii/description/
题目大意
给定一个循环序列,求其满足元素互不相邻的子序列的最大和。
思路分析
先考虑序列不循环的情况:
运用递归的思想,设k个元素的子序列最大和是
f(k)
,则 f(k) = max(f(k - 1), f(k - 2) + nums[k])
再考虑序列循环的情况:
如果序列循环,那么子序列不能同时包含第一个元素和最后一个元素。
因此把序列分成两种情况讨论即可。
实现代码
class Solution(object):
def rob(self, nums):
if len(nums) == 0:
return 0
if len(nums) == 1:
return nums[0]
nums1 = nums.copy()
nums1.pop(-1)
nums2 = nums.copy()
nums2.pop(0)
return max(f(nums1), f(nums2))
"""
:type nums: List[int]
:rtype: int
"""
def f(nums):
last, now = 0, 0
for i in nums:
last, now = now, max(last + i, now)
return now
运行结果
时间复杂度分析:O(n)
#120. Triangle
题目来源
https://leetcode.com/problems/triangle/description/
题目大意
给定一个三角矩阵,求从顶点到底端的最短路径,要求每次移动只能移到相邻结点。
思路分析
设第k行第i个结点的最短路径为
f(k)(i)
。 从底部开始遍历,第k-1行第i个结点的最短路径为第k行第i个结点的最短路径或第k行第i+1个结点的最短路径加上该结点。
即
f(k-1)(i) = row[k-1][i] + min(f(k)(i), f(k)(i+i))
实现代码
class Solution:
def minimumTotal(self, triangle):
"""
:type triangle: List[List[int]]
:rtype: int
"""
k = [0] * (len(g) + 1)
for row in g[::-1]:
for i in range(len(row)):
k[i] = row[i] + min(k[i], k[i+1])
return k[0]
运行结果
时间复杂度分析:O(n²)
#55. Jump Game
题目来源
https://leetcode.com/problems/jump-game/description/
题目大意
给定一个列表,列表的每个元素表示你能前进的最大步数,最开始时你在第一个列表所在的位置,之后你可以前进,问能不能到达最后一个元素位置。
思路分析
我们可以把jump的过程看成是染色,则需要枚举每一位时都在判断是否被染色过(从而决定是否能够到达该点且能否继续往前走),假设在某一瞬间,
index = m
的位置已经被染色了,那么index = n(n <= m)
的位置肯定已经被染色过了,我们维护一个最右边被染色的点,如果当前枚举点在该点的左侧,那么当前点已经被染色,否则即可停止遍历(因为右边的点再也不可能被染色到了)。 实现代码
class Solution:
def canJump(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
n = len(nums)
i = 0
maxjmp = 0
while i <= maxjmp:
maxjmp = max(maxjmp, nums[i] + i)
i += 1
if maxjmp >= n - 1:
return True
return False
运行结果
时间复杂度分析:O(n)
#134. Gas Station
题目来源
https://leetcode.com/problems/gas-station/description/
题目大意
给定一个循环序列,求起始位置,使得在起始位置以后得任意位置得序列和不小于0。
若不存在,则返回-1。
思路分析
注意以下关键原则:
1. 若序列和为负数,则一定不存在解。
2. 若序列和为0,则一定存在解,且该解唯一。
3. 若解唯一。假设从第
i
个元素开始判断,到第j
个元素恰好失败了。那么下一次判断只需从第j+1
个元素,而不是从第i+1
个元素。
实现代码
class Solution:
def canCompleteCircuit(self, gas, cost):
"""
:type gas: List[int]
:type cost: List[int]
:rtype: int
"""
a = [i - j for i, j in zip(gas, cost)]
n = len(a)
if sum(a) < 0:
return -1
i = -n
while i < 0:
s = 0
for j in range(i, i + n):
s += a[j]
if s < 0:
i = j + 1
break
if j == i + n - 1:
return i + n
return -1
运行结果
时间复杂度分析:O(n)
#148. Sort List
题目来源
https://leetcode.com/problems/sort-list/description/
题目大意
给定一个链表,使用o(nlogn)的时间复杂度和常量空间复杂度进行排序:
Sort a linked list in O(n log n) time using constant space complexity.
思路分析
归并排序。
实现代码
class Solution:
def sortList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
arr = []
while head != None:
arr.append(head.val)
head = head.next
arr = MergeSort(arr)
tmp = ListNode(0)
head = tmp
for i in arr:
tmp.next = ListNode(i)
tmp = tmp.next
return head.next
def MergeSort(arr):
if len(arr) <=1:
return arr
num = len(arr)/2
left = MergeSort(arr[:num])
right = MergeSort(arr[num:])
return Merge(left,right)
def Merge(left,right):
r,l=0,0
reslut=[]
while l<len(left) and r<len(right):
if left[l] < right[r]:
reslut.append(left[l])
l+=1
else:
reslut.append(right[r])
r+=1
reslut+= right[r:]
reslut+= left[l:]
return reslut
运行结果
#215. Kth Largest Element in an Array
题目来源
https://leetcode.com/problems/kth-largest-element-in-an-array/description/
题目大意
给定一个数组,求其第k个最大数。
思路分析
维护一个大小为k的heap。
实现代码
class Solution:
def findKthLargest(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
heap = []
for i in nums:
if len(heap) < k:
heap.append(i)
heap.sort()
elif heap[0] < i:
heap.pop(0)
heap.append(i)
heap.sort()
return heap[0]
运行结果
#23. Merge K Sorted Lists
题目来源
https://leetcode.com/problems/merge-k-sorted-lists/description/
题目大意
给定k个有序链表,将其合并。
思路分析
维护一个大小为k的heap。
实现代码
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
from heapq import heappush, heappop, heapify
class Solution:
def mergeKLists(self, lists):
"""
:type lists: List[ListNode]
:rtype: ListNode
"""
head = ListNode(-1)
curr = head
heap = [(lists[i].val, i, lists[i]) for i in range(len(lists)) if lists[i] != None]
heapify(heap)
i = len(lists)
while len(heap) != 0:
elem = heappop(heap)[2]
curr.next = elem
curr = curr.next
if elem.next != None:
heappush(heap, (elem.next.val, i, elem.next))
i += 1
return head.next
运行结果
时间复杂度分析:O(nlogk)
#4. Median of Two Sorted Arrays
题目来源
https://leetcode.com/problems/median-of-two-sorted-arrays/description/
题目大意
给定两个有序数组,求这些数据的中位数。
思路分析
合并有序数组即可。
实现代码
class Solution:
def findMedianSortedArrays(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: float
"""
n1, n2 = len(nums1), len(nums2)
t1, t2 = 0, 0
nums = []
while t1 < n1 and t2 < n2:
if nums1[t1] < nums2[t2]:
nums.append(nums1[t1])
t1 += 1
else :
nums.append(nums2[t2])
t2 += 1
while t1 < n1:
nums.append(nums1[t1])
t1 += 1
while t2 < n2:
nums.append(nums2[t2])
t2 += 1
i = len(nums)
if i == 0:
return 0
if i % 2 == 0:
return float(nums[i//2] + nums[i//2 - 1])/2
else:
return float(nums[i//2])
运行结果