Google面試題專題4 - leetcode41. First Missing Positive/25. Reverse Nodes in k-Group
阿新 • • 發佈:2018-12-04
41. First Missing Positive
題目描述
給定一無序整數陣列,找到丟失的最小正整數。
要求時間複雜度O(n),空間複雜度O(1)。
例子
Example 1:
Input: [1,2,0]
Output: 3
Example 2:
Input: [3,4,-1,1]
Output: 2
Example 3:
Input: [7,8,9,11,12]
Output: 1
思想
只需找到缺失的第一個正整數,所以不妨把所有正數放到對應的位置,再找到第一個位置不匹配的地方。
將數num移到num-1的位置。num的範圍為1~len(nums)
1)遍歷陣列,如果num的範圍在[1, len(nums)],且和當前位置不匹配,則將其交換到num-1的位置。繼續判斷num是否與位置匹配…
2)遍歷陣列,若i位置的數字num 不等於i+1,返回i+1
解法
class Solution(object):
def firstMissingPositive(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
i = 0
n = len(nums)
while i < n:
num = nums[i]
if 1 <= num <= n and num != nums[num-1]:
nums[num-1], nums[i] = nums[i], nums[num-1]
else:
i += 1
for i, num in enumerate(nums):
if num != i + 1:
return i + 1
return n + 1
25. Reverse Nodes in k-Group
題目描述
給定一個連結串列,每k個翻轉一次,返回最終的連結串列。
k是正整數,且小於等於連結串列長度。如果結點數不是k的整數倍,保留餘數不動。
要求常數空間。
例子
Given this linked list: 1->2->3->4->5
For k = 2, you should return: 2->1->4->3->5
For k = 3, you should return: 3->2->1->4->5
思想
(遞迴)
1)首先找到第k+1個結點,從第k+1個結點開始遞迴翻轉
2)翻轉前k個結點,與1)中翻轉的連結串列拼接。
(非遞迴)
考慮ABCDE,翻轉BCD。則翻轉BCD→DCB後,將A指向D,B指向E。
解法1
遞迴。第k個結點後-遞迴,前k個結點單獨處理。
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def reverseKGroup(self, head, k):
"""
:type head: ListNode
:type k: int
:rtype: ListNode
"""
# 首先找到第k+1個結點
cur = head
cnt = 0
while cur and cnt < k:
cur = cur.next
cnt += 1
# 長度不到k
if cnt != k:
return head
pre = self.reverseKGroup(cur, k)
cur = head
for _ in range(k):
temp = cur.next
cur.next = pre
pre, cur = cur, temp
return pre
解法2
非遞迴。reverseNextK()操作了k+2個結點,將k個結點翻轉後,與首尾拼接。
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def reverseKGroup(self, head, k):
"""
:type head: ListNode
:type k: int
:rtype: ListNode
"""
dummy = ListNode(-1)
dummy.next = head
p = dummy
while p:
p = self.reverseNextK(p, k)
return dummy.next
def reverseNextK(self, head, k):
# 長度小於k+1
p = head
for _ in range(k+1):
if not p:
return None
p = p.next
# tail, node1, node2.., nodek
pre, cur = head, head.next
tail = pre
node = cur
for _ in range(k):
temp = cur.next
cur.next = pre
pre, cur = cur, temp
# 和首連線 - tail.next = nodek
tail.next = pre
# 和尾(下一個的頭)連線
node.next = cur
return node