前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >漫谈递归-链表合并

漫谈递归-链表合并

作者头像
程序员小王
发布2019-03-06 15:34:47
5970
发布2019-03-06 15:34:47
举报
文章被收录于专栏:架构说架构说

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

认真阅读题目

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

示例:

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

线索

递归实现

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

实现

GO

代码语言:javascript
复制
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  
  } 
}

c++

代码语言:javascript
复制
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个链表。

代码

  • c
代码语言:javascript
复制
//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
代码语言:javascript
复制
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

分析

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

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

代码

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
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. 变化一步过程是什么
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-01-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Offer多多 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 第一个题目 合并两个有序链表
    • 认真阅读题目
      • 线索
        • 实现
        • 2. 难度升级 第二个问题 合并K个排序链表
          • 认真阅读题目
            • 分析
              • 代码
              • 第三个题目 148. 排序链表 难度有升级了
                • 题目描述
                  • 分析
                    • 代码
                    • 第四个题目 remove-duplicates-from-sorted-list-ii
                      • code
                      • remove-duplicates-from-sorted-list
                        • 83. 删除排序链表中的重复元素
                          • 分析
                            • code
                              • 总结
                              领券
                              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档