删除排序链表中的重复元素 83
终止条件:当前指针cur及cur.next为空;
public ListNode deleteDuplicates(ListNode head) {
ListNode cur = head;
while(cur!=null && cur.next!=null){
if(cur.val == cur.next.val){
cur.next = cur.next.next;
}else{
cur = cur.next;
}
}
return head;
}
思路:一边遍历、一边统计相邻节点的值是否相等,如果值相等就继续后移找到值不等的位置,然后删除值相等的这个区间
链表的头节点可能会被删除,要用dummy节点
public ListNode deleteDuplicates(ListNode head) {
if (head == null) {
return head;
}
ListNode dummy = new ListNode(0, head);
ListNode cur = dummy;
while (cur.next != null && cur.next.next != null) {
if (cur.next.val == cur.next.next.val) {
int x = cur.next.val;
while (cur.next != null && cur.next.val == x){
cur.next = cur.next.next;
}
} else {
cur = cur.next;
}
}
return dummy.next;
}
合并两个有序链表
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
ListNode newList = new ListNode(0);
ListNode preHead = newList;
while(list1 != null && list2 != null ){
if(list1.val <= list2.val){
newList.next = list1;
list1 = list1.next;
}else{
newList.next = list2;
list2 = list2.next;
}
newList = newList.next;
}
newList.next =list1 == null ? list2 : list1;
return preHead.next;
}
合并K个有序链表
时间复杂度分析:假设总共有N个节点,每次从队列中取出最小节点的时间复杂度是O(logN),而每个节点最多被取出和插入一次。因此,总的时间复杂度是O(NlogN)。在空间复杂度方面,我们使用了一个PriorityQueue来保存所有链表的头节点,所以空间复杂度是O(N)。
public ListNode mergeKLists(ListNode[] lists) {
if (lists == null || lists.length == 0) {
return null;
}
// 创建一个优先队列,指定排序按节点val升序
PriorityQueue<ListNode> queue = new PriorityQueue<>(
Comparator.comparingInt(node -> node.val));
// 将所有链表的头节点加入PriorityQueue
for (ListNode head : lists) {
if(head != null)
queue.offer(head);
}
// 创建一个dummy节点作为合并后链表的头节点,一个cur指针来追踪当前合并后链表的末尾节点。
ListNode cur = new ListNode(0);
ListNode dummy = cur;
// 不断从PriorityQueue中取出最小节点,并将其后续节点加入PriorityQueue
while (!queue.isEmpty()) {
ListNode minNode = queue.poll();
cur.next = minNode;
cur = cur.next;
if (minNode.next != null) {
queue.offer(minNode.next);
}
}
return dummy.next;
}