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

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]未通过,查看反转后的链表也确实反转过来了。一直搞不懂为什么会不通过。原来是递归后返回的链表==内存地址指向于原链表相同==在比较时并不是比较节点值,比较了节点的地址那当然一致了。因此要使用新建链表的方式进行反转后再对比。

#算法##数据结构##牛客##链表#
基础算法刷题题解 文章被收录于专栏

记录自己刷题的题解。坚持每天更新

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务