版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sinat_25991865/article/details/88292645
目录
1.合并两个有序链表
将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
解法:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
//新建一个空的头结点方便处理
ListNode head=new ListNode(-1);
//归并后的链表
ListNode p=head;
while(l1!=null && l2!=null){
if(l1.val<l2.val){
p.next=l1;
l1=l1.next;
}else{
p.next=l2;
l2=l2.next;
}
p=p.next;
}
if(l1!=null){
p.next=l1;
}
if(l2!=null){
p.next=l2;
}
return head.next;
}
}
2.排序链表
在O(nlogn)时间复杂度和常数级空间复杂度下,对链表进行排序。
示例:
输入: 4->2->1->3
输出: 1->2->3->4
解法:
采用归并排序:
- 找到链表中点(快慢指针法)
- 分别排序左半部分和右半部分
- 归并
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode sortList(ListNode head){
if(head==null|| head.next==null){
return head;
}
ListNode middle=findMiddle(head);
//排序右半边链表
ListNode right=sortList(middle.next);
middle.next=null;
//排序左半边链表
ListNode left=sortList(head);
//归并
return mergeTwoLists(left,right);
}
//快慢指针,慢指针一次走一步,快指针一次走两步,快指针达到末尾时,慢指针刚好在中间
private ListNode findMiddle(ListNode list){
ListNode chaser=list;
ListNode runner=chaser.next;
//结点数为偶数时,chaser停在前半部分链表节点的尾结点
while(runner.next!=null && runner.next.next!=null){
chaser=chaser.next;
runner=runner.next.next;
}
return chaser;
}
//归并两个有序链表
private ListNode mergeTwoLists(ListNode l1, ListNode l2) {
//新建一个空的头结点方便处理
ListNode head=new ListNode(-1);
//归并后的链表
ListNode p=head;
while(l1!=null && l2!=null){
if(l1.val<l2.val){
p.next=l1;
l1=l1.next;
}else{
p.next=l2;
l2=l2.next;
}
p=p.next;
}
if(l1!=null){
p.next=l1;
}
if(l2!=null){
p.next=l2;
}
return head.next;
}
}