[剑指Offer]21~24

[剑指Offer]21~24

学习使用工具

剑指Offer http://itmyhome.com/sword-means-offer/sword-means-offer.pdf

LeetCode的剑指Offer题库 https://leetcode.cn/problemset/all/

剑指 Offer 21. 调整数组顺序使奇数位于偶数前面

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数在数组的前半部分,所有偶数在数组的后半部分。

示例:

输入:nums = [1,2,3,4]
输出:[1,3,2,4] 
注:[3,1,2,4] 也是正确的答案之一。

提示:

  1. 0 <= nums.length <= 50000
  2. 0 <= nums[i] <= 10000

解法:

双指针,一个从头开始遍历,另一个从尾开始遍历。将第一个指针遍历遇到的偶数与第二个指针遍历遇到的奇数进行互换,直到两指针相遇,算法结束。时间复杂度O(N)。

def exchange(self, nums: List[int]) -> List[int]:
        if not nums:
            return nums
        if len(nums) == 1:
            return nums

        i = 0
        j = len(nums) - 1

        while(i < j):
            while(nums[i] % 2 == 1 and i < j):
                i += 1
            while(nums[j] % 2 == 0 and j > i):
                j -= 1
            if i < j:
                temp = nums[i]
                nums[i] = nums[j]
                nums[j] = temp
                i += 1
                j -= 1

        return nums

剑指 Offer 22. 链表中倒数第k个节点

输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。

例如,一个链表有 6 个节点,从头节点开始,它们的值依次是 1、2、3、4、5、6。这个链表的倒数第 3 个节点是值为 4 的节点。

示例:

给定一个链表: 1->2->3->4->5, 和 k = 2.

返回链表 4->5.

解法:

双指针,首先都指向头结点,随后一个指针向后移动k-1节点。之后两个指针一起开始遍历,当靠后的指针遍历到最后一个节点时,返回靠前的指针。

def getKthFromEnd(self, head: ListNode, k: int) -> ListNode:
        if k == 0:
            return None

        t = head
        p = head
        for i in range(k - 1):
            p = p.next

        while(p.next):
            t = t.next
            p = p.next

        return t

剑指 Offer 24. 反转链表

定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

示例:

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

限制:

0 <= 节点个数 <= 5000

解法:

经典的反转链表题,头插法。

def reverseList(self, head: ListNode) -> ListNode:
        if not head:
            return None
        if head.next == None:
            return head

        temp = head
        h = head.next
        hn = head.next

        temp.next = None

        while(hn):
            hn = hn.next
            h.next = temp
            temp = h
            h = hn

        return temp

剑指 Offer 25. 合并两个排序的链表

输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。

示例1:

输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4

限制:

0 <= 链表长度 <= 1000

解法:

Dummyhead,一个指针记录结果链表当前值,另外两个指针分别遍历两个链表。比对两个指针值,将小的那个加入结果链表,且指针后移,直到其中一个链表被遍历完。随后,将剩下一个链表的剩下部分加入结果链表。

def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        if not (l1 or l2):
            return None
        if not l1:
            return l2
        if not l2:
            return l1

        head = ListNode(0)
        temp = head

        while(l1 and l2):
            if l1.val < l2.val:
                temp.next = l1
                l1 = l1.next
                temp = temp.next
            else:
                temp.next = l2
                l2 = l2.next
                temp = temp.next
            
        if l1:
            temp.next = l1
        if l2:
            temp.next = l2

        return head.next
posted @ 2023-03-06 14:21  无机呱子  阅读(1)  评论(0编辑  收藏  举报