LeetCode 打卡 Day7

题目如下:

 方法一

       暴力求解了,想到最直接的方法就是直接对两个链表进行遍历,将所有的数据都直接存下来,然后对这些数据进行排序,根据排序结果构建新的链表并返回结果。

使用C++编程

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        int s[100];
        ListNode* temp = l1;
        int i=0;
        while(temp!=nullptr){   
            s[i++]=temp->val;
            temp = temp->next;
        }
        temp = l2;
        while(temp!=nullptr){
            s[i++]=temp->val;
            temp = temp->next;
        }
        if(i!=0){
            sort(s,s+i);
            ListNode* l = new ListNode(s[0]);
            ListNode* t = l;
            for(int j=1;j<i;j++){
                t->next = new ListNode(s[j]);
                t = t->next;
            }
            return l;
        }
        else
            return nullptr;
    }
};

提交结果如下

 方法二

因为题目以说明两个链表均按非递减排序,所以设想能否固定一个链表,将另一个链表直接穿插进去,这样经过一次遍历即可完成对整个链表的排序。

两个链表存在以下三种不同的情况:

1)两个链表均非空:将两个链表重新排序;

2)一个链表为空,一个链表非空:直接返回该非空链表;

3)两个链表均空:直接返回空指针。

使用Java编程

写半天写出个错误示例来,说是链表中出现了环的情况,链表的结点真的晕啊,绕来绕去把自己绕进去了,放弃debug了,把错误代码粘在这里了。去看答案学习了。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if(l1!=null && l2!=null){   //情况一: 两个链表均非空
            //目标:打碎l2,在l1找合适的位置将l2穿插进去
            ListNode t = l1;
            while(l2!=null){
                int a2 = l2.val;
                ListNode start = l2;   //l2起点
                while(l1.next.next!=null && !(a2>l1.val && a2<l1.next.val))
                    l1 = l1.next;
                //出循环有两种可能的情况1、l1是链表倒数第二个;2、l1到l1的next是l2片段的插入位置
                int a1 = l1.next.val;
                while(l2.next!=null && l2.next.val<=a1)
                    l2 = l2.next;
                ListNode end = l2;     //l2终点
                ListNode temp = l1.next;
                l1.next = start;
                end.next = temp;
                l1 = temp;
                if(l1.next==null){
                    l1.next = l2.next;
                    return t;
                }
                l2 = l2.next;
            }
            return t;
        }
        else if(l1!=null && l2==null){  //情况二:l1非空,l2为空
            return l1;
        }
        else if(l1==null && l2!=null){  //情况三:l1为空,l2非空
            return l2;
        }
        else    //情况四:两个链表均空
            return null;
    }
}

答案一:递归

千算万算忘记了还能递归,其实整个思路很简单,每次比较链表头节点的大小,当有一个链表为空时返回非空的链表。

java编程

class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        if(l1==null)
            return l2;
        else if(l2==null)
            return l1;
        else if(l1.val<l2.val){
            l1.next = mergeTwoLists(l1.next,l2);
            return l1;
        }
        else {
            l2.next = mergeTwoLists(l1,l2.next);
            return l2;
        }
    }
}

提交结果如下

 答案二:迭代

看完两个答案后,感觉我之前的思路过于复杂,总感觉将链表完全拆开重组极耗费时空复杂度却忽略了两个链表非递减排列的事实,而且算法是否复杂应该经过具体的复杂度计算衡量,而不是我这样靠感觉判断。其实整体遍历一遍将节点重新排序即可,完全不需要那么复杂的思路。

C++编程

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode* prev = new ListNode(-1);
        ListNode* ret = prev;
        while(l1!=nullptr && l2!=nullptr){
            if(l1->val<=l2->val){
                prev->next = l1;
                l1 = l1->next;
            }
            else{
                prev->next = l2;
                l2 = l2->next;
            }
            prev = prev->next;
        }
        if(l1 == nullptr)
            prev->next = l2;
        else
            prev->next = l1;
        return ret->next;
    }
};

 运行结果

 相比之下,简单的迭代运行结果居然还没有我最开始的暴力求解运行时间短😂

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值