链表排序

1. 第一个题目 合并两个有序链表

认真阅读题目

将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

示例:

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

线索

递归实现

新链表 是有将两个有序链表合并成的
假设有方法mergeTwoLists能实现这样功能。
通过大小判断之后 继续这个方法

实现

  1. go
    /**
    描述:
    1
    Time complexity: O(n)
    Space complexity: O(0)
    **/
func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode {
    if l1 == nil {
        return l2
    }
    if l2 == nil {
        return l1
    }

    if l1.Val < l2.Val {
        l1.Next = mergeTwoLists(l1.Next, l2)
        return l1
    } else {
        l2.Next = mergeTwoLists(l1, l2.Next)
        return l2
    }
}
  1. c++
class Solution {
public:
    //Time complexity: O(n)
    //Space complexity: O(0)
    //Recursion
    //输入:1->2->4, 1->3->4
    //输出:1->1->2->3->4->4
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2)
    {
        if(l1 ==NULL)
        {
             return l2;
        }
        if(l2 ==NULL)
        {
            return l1;
        }
        if(l1->val<l2->val)
        {
           l1->next=mergeTwoLists(l1->next,l2);
           return l1;
        }else
        {
           l2->next=mergeTwoLists(l1,l2->next);
           return l2;
        }
    }
};

2. 难度升级 第二个问题 合并K个排序链表

认真阅读题目

  1. 合并K个排序链表

合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。

示例:
输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6

关键:把每个链表看成一个元素,vector<元素>

分析

问题1. 这是k个 不是2个 感觉无从下手,转成成22合并
问题2. k个链表如何,通过什么方式知道 已经完成排序了呢。

步骤
1.如果是一个链表(从最简单开始) 就不需要合并 这就是结果

  1. 如果是多个 采用归并排序。对象就是n个链表。


    什么情况适合递归?while?

代码

  • c
//Time complexity: O(logn)
    //Space complexity: O(0)
    ListNode* mergeKLists(vector<ListNode*>& lists)
    {
       int n=lists.size();
        if (n ==0)
        {
            return NULL;
        }
       return mergeLists(lists,0,n-1);
    }
     //
     ListNode* mergeLists(vector<ListNode*>& lists,int begin,int end)
     {
        //递归推出条件,只有一个元素
        if(begin == end)
        {
           return lists[begin];
        }

        int mid=(begin+end)/2;

        ListNode* first=mergeLists(lists,begin,mid);
        ListNode* second=mergeLists(lists,mid+1,end);

        return mergeTwoLists(first,second);

     }
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2)
    {
        if(l1 ==NULL)
        {
             return l2;
        }
        if(l2 ==NULL)
        {
            return l1;
        }
        if(l1->val<l2->val)
        {
           l1->next=mergeTwoLists(l1->next,l2);
           return l1;
        }else
        {
           l2->next=mergeTwoLists(l1,l2->next);
           return l2;
        }
    }
  • go
func merge_K_Lists(lists []*ListNode) *ListNode {
    if len(lists) == 0 {
        return nil
    }
    return sortmerge(lists, 0, len(lists)-1)
}
func sortmerge(lists []*ListNode, begin int, end int) *ListNode {
    if begin >= end {
        return lists[begin]
    }
    mid := (begin + end) / 2
    p1 := sort_merge(lists, begin, mid)
    p2 := sort_merge(lists, mid+1, end)
    return mergeTwoLists(p1, p2)

}

第三个题目 148. 排序链表 难度有升级了

题目描述

在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。

示例 1:

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

分析

链表无法通过下标直接定位 听过其他方法都不很合适
采用归并排序,数组通过下标来分段处理的,

链表如何分段? 指针特点出来了

代码

func sortList(head *ListNode) *ListNode {
    //只有一个元素 归并排序推出条件
    if head == nil || head.Next ==nil{
        return head
    }

    fast := head
    low := head
    for fast!=nil &&fast.Next!=nil&&fast.Next.!=nil{
        low=low.Next
        fast=fast.Next.Next
        
    }
     
    //一个链表分割成2个链表
    mid:=low.Next
    low.Next=nil //非常重要
    
    first := sortList(head) 
    second := sortList(mid)
    
    return mergeTwoLists(first,second)

}

第四个题目 remove-duplicates-from-sorted-list-ii

  1. 删除排序链表中的重复元素 II

给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。

示例 1:
输入: 1->2->3->3->4->4->5
输出: 1->2->5
示例 2:
输入: 1->1->1->2->3
输出: 2->3

题目理解

相同元素必须全部删除,如果比较相同元素,
需要2个变量,cur ,next
[1,1,1,1] 最后一个元素1和谁比较呢

code

class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        if(head ==NULL || head->next ==NULL)
         {
            return head;
         }
         int pre=head->val;
         ListNode* temp;

         if(head->val ==head->next->val)
         {
             while(head && pre ==head->val)
             {
                temp=head;
                head=head->next;
                temp->next=NULL;
                delete temp;
             }
            return deleteDuplicates(head);

         }else
         {
             head->next=deleteDuplicates(head->next);
             return head;
         }
    }
};

remove-duplicates-from-sorted-list

83. 删除排序链表中的重复元素

给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次
示例 2:
输入: 1->1->2->3->3
输出: 1->2->3

分析

链表问题没有简单问题
method 1

循环遍历 比较当前元素和下个元素
如果相同 删除当前元素(删除下一个元素会有问题的)
继续遍历
最坏情况 全部相同 [1,1,1,1,1,1,1]

code

struct ListNode* deleteDuplicates(struct ListNode* head) {
    if(head ==NULL ||head->next ==NULL)
   {
      return head; //只有一个元素
   }

   //compare
   if(head->val ==head->next->val)
   {
     struct ListNode* temp=head;
     head=head->next;
     temp->next=NULL;
     free(temp);
     return deleteDuplicates(head);

   }else
   {
     head->next=deleteDuplicates(head->next);
     return head;
   }
}

总结

  1. 递归结束条件是什么 一个数组,一个链表 ,一个tree
  2. 变化一步过程是什么
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,110评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,443评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,474评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,881评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,902评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,698评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,418评论 3 419
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,332评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,796评论 1 316
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,968评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,110评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,792评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,455评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,003评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,130评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,348评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,047评论 2 355