Leetcode、牛客、PTA原题:“回文链表”和“合并有序链表”

一、题目要求:回文链表

在这里插入图片描述

解题:

代码:

class Solution {
    public boolean isPalindrome(ListNode head) {
      ListNode p1 = replace(head);
      while(head != null && p1 != null){
        // 存在不同值的节点时
        if(head.val != p1.val){
          return false;
        }
        head = head.next;
        p1 = p1.next;
      }
      return true;
    }

    // 反转链表
    public ListNode replace(ListNode head){
      //        创建一个新链表,n1为头指针先指向空
        ListNode n1 = null;
//        创建一个p节点,获取旧链表
        ListNode p = head;
//        遍历旧链表,当不为空说明还有下一节点
        while (p != null){
//            使用头插入,将每次遍历到的节点插入到新链表头
            n1 = new ListNode(p.val, n1);
//            旧链表的下一节点
            p = p.next;
        }
//        返回新链表
        return n1;
    }
}

思路: 先将原链表反转,将反转后的链表与原链表进行逐一节点值的对比。反转链表的讲解请参考反转链表
关键点: 在反转链表时,不可以使用递归算法进行链表的反转,因为使用链表的话,其实链表的地址是没有发生改变的。因此在比较时无法通过某些测试点。

二、题目要求:合并两个有序链表

在这里插入图片描述

题解:

代码:

class Solution {
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
      // // 创建一个带有哨兵节点新的链表
      // ListNode s = new ListNode(-1,null);
      // // 新链表的指针
      // ListNode p = s;
      // // 判断两个链表的每个节点比较大小
      // while(list1 != null && list2 != null){
      //   // list1<list2的情况
      //   if(list1.val < list2.val){
      //     // 将list1的节点值链接到新链表s
      //     p.next = list1;
      //     // 将list1往后移一位
      //     list1 = list1.next;
      //   }else{
      //     // 同理
      //     p.next = list2;
      //     list2 = list2.next;
      //   }
      //   // 将新链表添加成功一个节点后往后移一位
      //   p = p.next;
      // }
      // // 判断list1和list2那个链表先不为空,将剩下的链表接到新链表中
      // if(list2 != null){
      //   p.next = list2;
      // }
      // if(list1 != null){
      //   p.next = list1;
      // }
      // // 返回带有哨兵节点的新链表
      // return s.next;


      // 递归实现
      if(list1 == null){
        return list2;
      }
      if(list2 == null){
        return list1;
      }
      if(list1.val < list2.val){
        // 链表1往后移一位,继续与p2当前节点比较。并返回当前节点
        list1.next = mergeTwoLists(list1.next,list2);
        return list1;
      }else{
        list2.next = mergeTwoLists(list1,list2.next);
        return list2;
      }

    }

思路1:
创建一个带有指针p哨兵节点的新链表p,初始化状态时将s=null,p = s。对于链表l1和链表l2。首先:保证两个链表都未到尾节点(null),对l1.val 与 l2.val进行比较,若l1.val < l2.val时,将l1.val连接到p然后节点往后移一位。对于l1.val > l2.val的情况也是同理处理即可。
最后要对那个链未空进行确定,将==未空链表的剩下节点全部连接到p即可。
图解:
在这里插入图片描述

思路2: 递归实现
递归实现时,无需创建新的链表。若l1.val < l2.val,则递归让l1后移一位,但l2留在原地。对于l1.val>l2.val的情况只需要做相反操作即可。最后一步处理的是那个链表上的节点就将那个链表进行返回即可得到合并后的链表
图解:
在这里插入图片描述

总结:

一开始对于回文链表使用递归反转链表后于原链表进行对比时,总是有一个测试点[1,1,2,1]未通过,查看反转后的链表也确实反转过来了。一直搞不懂为什么会不通过。
原来是递归后返回的链表内存地址指向于原链表相同在比较时并不是比较节点值,比较了节点的地址那当然一致了。因此要使用新建链表的方式进行反转后再对比。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

自拍拍到鬼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值