[剑指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] 也是正确的答案之一。
提示:
0 <= nums.length <= 50000
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