Sort List 【leetCode】

本文详细介绍了如何使用合并排序算法对单链表进行O(n log n)时间复杂度的排序,避免了使用递归方式,并在常数空间复杂度下实现了这一目标。通过实现代码示例,展示了二分法和窗口调整策略来高效地对链表元素进行排序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录:
1、题目及分析
    1.1 题目
    1.2 分析

1、题目及分析
1.1 题目:
    Sort a linked list in O(n log n) time using constant space complexity.
1.2 分析
    O(n log n)的复杂度,所以不能采用冒泡等,这里采用合并排序算法,且为了不采用递归的方式,所以得到如下代码。

2、实现

 // Definition for singly-linked list.
  class ListNode {
      int val;
      ListNode next;
      ListNode(int x) {
          val = x;
          next = null;
      }
  }

public class SortList {

    public int length(ListNode head){ //求链表的长度
        int count = 0;
        ListNode h = head;
        while(null != h){
            count ++;           
            h = h.next;
        }
        return count;
    }
    public ListNode sortList(ListNode head) {//返回排序的结果
        int len = length(head); 
        //System.out.println(len);
        int window = 2;//
        ListNode pointL = null;
        ListNode pointR = null;
        ListNode tmp = null;
        ListNode tmp2 = null;
        ListNode headPointer = new ListNode(0); //定义一个头指针
        ListNode headPointerTmp = head;         //定义一个暂头指针
        headPointer.next = head;    //将头指针指向传入的链表
        headPointerTmp = headPointer;      //暂存头指针指向头指针
        if(0 == len || 1== len) return head; //如果长度为1,则直接返回

        while(window/2 < len){  //二分法每个区间用2^n大小表示,如果len=5,那么必须运算到window=8才能结束
                                //这里采用 len大于window/2 当len=5时,8/2=4仍然运行,16/2=8才结束
            for(int i=len ; i>0; i-=window){
                pointL = headPointerTmp;
                pointR = headPointerTmp;

                for(int k=window/2; k>0; k--){
                    if(null == pointR.next) break;
                    pointR =  pointR.next;//移动指针
                }

                for(int j=window/2; j>0; )  {//由于使用分治,所有待排序的,都已经按照一定顺序排列
                                             //R的操作最多window/2次
                    if(pointR == pointL || null == pointR.next) break; //L中所有都遍历了就结束
                    if(pointR.next.val < pointL.next.val){//满足条件则进行插入操作
                        /* pre->A->B->C>D  要将C插入到A之前
                         * pointL = pre; pointR = C;
                         * pre->C;C->A;B->D
                         */
                        tmp = pointL.next;          //保存A        
                        tmp2 = pointR.next.next;    //保存D
                        pointL.next = pointR.next;  //pre->C 
                        pointL.next.next = tmp;     //C->A
                        pointR.next = tmp2;         //B->D
                        pointL = pointL.next;       //后移一位
                        //print(headPointer.next);
                        j--;    //每次进行插入后,进行j--
                    }
                    else{
                        pointL = pointL.next; 
                    }
                }
                for(int k=window; k>0; k--){    //将指针移动到下一个windonw内
                     if(null == headPointerTmp.next) break; //这里可以处理非2^n长度的链表
                    headPointerTmp = headPointerTmp.next;   
                }

            }
            
            window = window * 2; //扩大窗口
            headPointerTmp = headPointer;//重新指向最开始
        }
        return headPointer.next; //返回头结点
    }
    public void print(ListNode head){
        ListNode point = head;
        for(int m=length(head); m>0; m--){
            System.out.print(point.val + " ");
            point = point.next;
        }
        System.out.println();
    }
    public static void main(String[] args) {
        ListNode l1 = new ListNode(4);
        ListNode l2 = new ListNode(2);
        ListNode l3 = new ListNode(1);
        ListNode l4 = new ListNode(3);
        ListNode l5 = new ListNode(5);
        ListNode l6 = new ListNode(-1);
        ListNode l7 = new ListNode(-2);
        ListNode l8 = new ListNode(-100);
        ListNode l9 = new ListNode(-1000);
        ListNode l10 = new ListNode(-1000);
        ListNode k = null;
        
        ListNode lm = null;
        SortList s = new SortList();

        //k.next = l1;
        l1.next = l2;
        l2.next = l3;
        l3.next = l4;
        l4.next = l5;
        l5.next = l6;
        l6.next = l7;
        l7.next = l8;
        l8.next = l9;
        l9.next = l10;


        lm = s.sortList(l1);
        s.print(lm);
        //System.out.println(lm.val);
        //System.out.println(lm.next.val);

    }
}


### 使用 `sort` 函数在 LeetCode 上实现数组或列表排序 #### C++ 实现 在 C++ 中,可以使用标准库中的 `std::sort()` 来对向量 (vector) 进行排序。此函数采用迭代器作为参数来指定要排序的范围。 ```cpp class Solution { public: void sortVector(std::vector<int>& vec) { std::sort(vec.begin(), vec.end()); // 对整个vec升序排列 } }; ``` 上述代码展示了如何定义一个名为 `Solution` 的类,并在其内部创建了一个成员函数 `sortVector`,该函数接收一个整数类型的引用向量并对其进行排序[^1]。 为了降序排列,则需提供自定义比较谓词: ```cpp bool descending(int a, int b){ return a > b; } //... std::sort(vec.begin(), vec.end(), descending); ``` 这里通过传递第三个参数给 `std::sort()`, 即实现了按特定规则(这里是大于号表示的大于关系)来进行排序操作。 #### Python 实现 Python 提供了内置的方法 `.sort()` 和全局函数 `sorted()` 可用于原地修改对象或返回新的已排序序列副本。下面的例子展示怎样在一个解决方案类里调用这些功能: ```python from typing import List class Solution: def sortList(self, lst: List[int]): lst.sort() # 原位排序lst @staticmethod def get_sorted_copy(lst: List[int]) -> List[int]: return sorted(lst) # 返回一个新的有序列表而不改变原始数据 ``` 这段代码同样构建了一个叫做 `Solution` 的类,在其中包含了两种不同的方式来处理输入列表 `lst`:一种是在原有基础上直接进行排序;另一种则是生成一份经过排序的新列表副本[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值