ListNode相关要点
前言
最近在刷LeetCode,遇到一些似曾相识但又模棱两可的知识点,这里做一下总结,本文是Java中ListNode语法及操作的梳理。
类结构如下
public class ListNode {
int val; //结点值
ListNode next; //用来指向下一个结点的ListNode对象
ListNode() {}
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
}
上面是官方文档定义,下面做一下解释:
链表是一种数据结构,由数据和指针构成,指针指向下一个结点
Java ListNode 就是用Java定义实现的链表结构
ListNode 本质上是一个Java类,它具有类所有的特性,比如,创建对象;通过对象访问类的成员变量和成员方法
创建一个ListNode对象:ListNode node = new ListNode();
node.val 表示当前所在结点的值,node.next 表示当前结点所指向下一个结点的地址值
当然了,ListNode也有泛型,使用泛型可以兼容不同的的数据类型
class ListNode<E>{ //类名 :Java类就是一种自定义的数据结构
E val; //数据 :节点数据
ListNode<E> next; //对象 :引用下一个节点对象。在Java中没有指针的概念,Java中的引用和C语言的指针类似
ListNode(E val){ //构造方法 :构造方法和类名相同
this.val=val; //把接收的参数赋值给当前类的val变量
}
}
LeetCode例题
合并两个有序链表:将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。(力扣21题)
这道题应该是非常非常的简单,思路也特别的好找,记得大学刚学数据结构的时候就接触过这种题目。今天作为练手,拿这道题来熟悉一下ListNode的相关
知识。
我的思路:
首先设置两个指针,pre指针用来每次比较后的后移,resNode指针用来最后的时候返回整条新链。第一次比较两条链的第一
个值,取较小的作为新链的第一个值,并用pre指针进行连接,此时pre指针后移(这里后移到刚刚进行连接的结点),然后
把刚刚连接的结点从旧链中去掉,接着进行第二次比较两条链的第一个值........直到其中一条链为null时停止,然后把不
为null的链直接拼接在新链的后面,最后返回即可。
我的代码:
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode reslist = new ListNode(-1);
ListNode pre = reslist;
if (l1 == null) {
return l2;
} else if(l2 == null) {
return l1;
} else if (l1 == null && l2 == null) {
return null;
} else {
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
pre.next = l1;
pre = l1;
l1 = l1.next;
} else {
pre.next = l2;
pre = l2;
l2 = l2.next;
}
}
pre.next = l1 == null ? l2 : l1;
return reslist.next;
}
}
}
显然,本人的代码有些稚嫩,有些地方是可以优化的。
官方AC代码:
思路一:递归
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;
}
}
}
思路二:迭代
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode prehead = new ListNode(-1);
ListNode prev = prehead;
while (l1 != null && l2 != null) {
if (l1.val <= l2.val) {
prev.next = l1;
l1 = l1.next;
} else {
prev.next = l2;
l2 = l2.next;
}
prev = prev.next;
}
// 合并后 l1 和 l2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可
prev.next = l1 == null ? l2 : l1;
return prehead.next;
}
}
具体详情请参考链接:https://leetcode-cn.com/problems/merge-two-sorted-lists/solution/he-bing-liang-ge-you-xu-lian-biao-by-leetcode-solu/
总结
兴趣打开知识的大门,刷题无非就是寻找更多更优的解题思路,有时候官方题解会让你豁然开朗,有时候评论区的大神会让你
直呼卧槽,不管哪种,都请继续往下走!