High Level : 两个LinkedList分别两个指针从各自的head开始-->谁小取谁,取谁移谁。(也就是从各自的head开始,每次将两个指针所在的值进行比较,取出小的一个,然后将其指针向后移动,继续重复这个操作),直到其中一个List先取完了,再把另外一个List剩下的链接上去。
public ListNode merge(ListNode one,ListNode two) {
// corner case
if (one == null && two == null) { // 两个要合并的List都是null
return null;
}
if (one == null || two == null) { // 两个其中有一个是null,这里本应该包括两个都是null的情况
return one == null?two:one; // 但是两个都是null,已经在上边排除了,才能走到这一步
}
// 两个List都是正常的List
// 创建两个指针分别指向两个head(one和two)
ListNode cur1 = one;
ListNode cur2 = two;
// 接下来比较one和two值的大小,小的一个当作新的要merge的head
ListNode head;
if (one.value < two.value) {
head = one;
cur1 = cur1.next; // one成为head后,以one为head的List在后面与以two为head的List比较的
} // 时候就不应在包含one,所以cur1应该是one的下一个(往后移动一个)
else {
head = two; // 和one成为head同理
cur2 = cur2.next;
}
// 确定完head后,开始“谁小取谁,取谁移谁”
ListNode cur = head;
while (cur1 != null && cur2 != null) {
if (cur1.value < cur2.value) { // 谁小
cur.next = cur1; // 取谁
cur1 = cur1.next; // 取谁移谁
curr = cur.next; // cur也要同步往后移
}
else {
cur.next = cur2;
cur2 = cur2.next;
cur = cur.next;
}
}
// 跳出while后也就是,其中一个List已经被取完了,那把还没取完的(!= null)的List链接到cur
// 后面就ok了
if (cur1 != null) {
cur.next = cur1;
}
if (cur2 != null) {
cur.next = cur2;
}
return head;
这里涉及到head的变化,可以使用Dummy Node
即创建一个dummy node,当作一个“head”,这样做的好处是省去上面代码中比较one和two产生新的head的过程,直接进行“谁小取谁,取谁移谁”的操作,把第一个小的链接到dummy后面,最后return dummy.next就好了
public ListNode merge(ListNode one,ListNode two) {
if (one == null && two == null) {
return null;
}
if (one == null || two == null) {
return one == null?two:one;
}
ListNode cur1 = one;
ListNode cur2 = two;
ListNode dummy = new ListNode(-1); // 随便赋值
ListNode cur = dummy;
while (cur1 != null && cur2 != null) {
if (cur1.value < cur2.value) {
cur.next = cur1;
cur1 = cur1.next;
}
else {
cur.next = cur2;
cur2 = cur2.next;
}
cur = cur.next; // 无论走上边哪一步cur都要移动,可以直接写在最后
}
if (cur1 != null) {
cur.next = cur1;
}
if (cur2 != null) {
cur.next = cur2;
}
return dummy.next;
}