字节跳动高频面试题之排序奇升偶降链表

266 阅读2分钟

前言

本系列是对企业题库LeetcodeTop的补充,汇总力扣上找不到的面试高频题。

来看一下几篇面经的原文叙述

[1] 链表,奇数位置按序增长,偶数位置按序递减,如何能实现链表从小到大?(2020.10 字节跳动-后端)
[2] 奇偶生序倒序链表的重新排序组合,例如:18365472(2020.08 字节跳动-后端)
[3] 1->4->3->2->5 给定一个链表奇数部分递增,偶数部分递减,要求在O(n)时间复杂度内将链表变成递增,5分钟左右(2020.07 字节跳动-测试开发)
[4] 奇数位升序偶数位降序的链表要求时间O(n)空间O(1)的排序?(2020.07 字节跳动-后端)

可见,无论是后端还是测试开发,都曾被考察过这道题,而且这道题并非力扣上的题目,大家一定要注意!!

题目描述

给定一个奇数位升序,偶数位降序的链表,将其重新排序。

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

题目分析

  1. 按奇偶位置拆分链表,得1->3->5->7->NULL和8->6->4->2->NULL
  2. 反转偶链表,得1->3->5->7->NULL和2->4->6->8->NULL
  3. 合并两个有序链表,得1->2->3->4->5->6->7->8->NULL

思路很清晰,实现起来有些难度。第2步和第3步分别对应的力扣206. 反转链表力扣21. 合并两个有序链表,而第1步的解法与力扣328. 奇偶链表差不多。

如果搞懂这3道leetcode,那么本篇文章的这道题肯定不在话下了。

代码

class ListNode:    
    def __init__(self, x):        
        self.val = x        
        self.next = None

class Solution:    
    def sortOddEvenList(self,head):     
        if not head or not head.next:      
            return head        
        oddList,evenList = self.partition(head)        
        evenList = self.reverse(evenList)        
        return self.merge(oddList,evenList)    

    def partition(self, head: ListNode) -> ListNode:        
        evenHead = head.next        
        odd, even = head, evenHead        
        while even and even.next:            
            odd.next = even.next            
            odd = odd.next            
            even.next = odd.next            
            even = even.next        
        odd.next = None        
        return [head,evenHead]    
    def reverse(self,head):        
        dumpy = ListNode(-1)        
        p = head        
        while p:            
            temp = p.next            
            p.next = dumpy.next            
            dumpy.next = p            
            p = temp        
        return dumpy.next    
    def merge(self,p,q):        
        head = ListNode(-1)        
        r = head        
        while p and q:            
            if p.val <= q.val:               
                r.next = p                
                p = p.next            
            else:                
                r.next = q                
                q = q.next            
            r = r.next        
        if p:            
            r.next = p        
        if q:            
            r.next = q        
        return head.next

参考

  1. www.nowcoder.com/discuss/546…
  2. www.nowcoder.com/discuss/476…
  3. www.nowcoder.com/discuss/460…
  4. www.nowcoder.com/discuss/449…