1. 程式人生 > >Google面試題專題4 - leetcode41. First Missing Positive/25. Reverse Nodes in k-Group

Google面試題專題4 - leetcode41. First Missing Positive/25. Reverse Nodes in k-Group

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