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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值