算法链表


文章目录

    • 删除所有含有重复数字的节点
      • 非递归代码分析
      • 递归代码分析
    • 合并K个链表
    • 排序一个无序链表
      • 归并 自顶向下
    • 分隔链表
      • 奇偶排序链表
    • 链表模拟大数相加
      • 代码描述
    • 复杂链表的复制
      • 代码分析

删除所有含有重复数字的节点 给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。
非递归代码分析
slow用来指向排除重复后的最后一个节点,fast用来指向重复元素的最后一个节点
如果slow.next==fast说明中间没有重复元素可以直接slow=slow.next;
不然说明fast的 元素需要跳过
使用dummyhead也解决了从头节点开始重复的情况
class Solution { public ListNode deleteDuplicates(ListNode head) { if (head == null) return head; ListNode dummy = new ListNode(-1); dummy.next = head; ListNode slow = dummy; ListNode fast = dummy.next; while(fast!=null){ while(fast.next!=null&&fast.val==fast.next.val) fast=fast.next; if(slow.next==fast) slow = fast; else slow.next=fast.next; fast=fast.next; } return dummy.next; } }

递归代码分析
class Solution { public ListNode deleteDuplicates(ListNode head) { if (head == null) return head; if(head.next!=null&&head.val==head.next.val){ while(head.next!=null&&head.val==head.next.val) head=head.next; return deleteDuplicates(head.next); } else head.next = deleteDuplicates(head.next); return head; } }

合并K个链表 归并排序的思想
import java.util.*; /** * Definition for singly-linked list. * public class ListNode { *int val; *ListNode next; *ListNode(int x) { val = x; } * } */ class Solution { public ListNode mergeTwoLists(ListNode l1, ListNode l2) { if(l1==null) return l2; if(l2==null) return l1; if(l1.val<=l2.val){ l1.next=mergeTwoLists(l1.next,l2); return l1; } else{ l2.next =mergeTwoLists(l1,l2.next); return l2; } }public ListNode mergeKLists(ListNode[] lists,int l ,int r ){ if(l==r) return lists[l]; int mid = l+(r-l)/2; ListNode l1 =mergeKLists(lists, l ,mid ); ListNode l2 = mergeKLists(lists, mid+1 , r ); return mergeTwoLists(l1, l2); }public ListNode mergeKLists(ListNode[] lists) { if(lists==null||lists.length==0) return null; returnmergeKLists(lists,0,lists.length-1); } }

排序一个无序链表 代码分析
归并 自顶向下
import java.util.List; class Solution {public ListNode sortList(ListNode head) { if(head==null||head.next==null) return head; ListNode slow = head; ListNode fast = head.next; while (fast!=null&&fast.next!=null){ slow=slow.next; fast=fast.next.next; } ListNode temp = slow.next; slow.next = null; ListNode pre = sortList(head); ListNode pro = sortList(temp); ListNode dummyhead = new ListNode(-1); ListNode cur = dummyhead; while (pre!=null&&pro!=null){ if (pre.val

分隔链表
/** * Definition for singly-linked list. * public class ListNode { *int val; *ListNode next; *ListNode(int x) { val = x; } * } */ class Solution { public ListNode partition(ListNode head, int x) {ListNode prehead = new ListNode(-1); ListNode prohead = new ListNode(-1); ListNode pre = prehead; ListNode pro = prohead; while(head!=null){ if(head.val

奇偶排序链表
原理和根据上题一样 通过flag分成两块 然后连接
/** * Definition for singly-linked list. * public class ListNode { *int val; *ListNode next; *ListNode(int x) { val = x; } * } */ class Solution { public ListNode oddEvenList(ListNode head) { if(head == null||head.next == null) return head; ListNode oddhead = new ListNode(-1); ListNode evenhead = new ListNode(-1); ListNode odd = oddhead; ListNode even = evenhead; boolean flag = true; while(head!=null){ if(flag){ odd.next=head; ListNode temp = head.next; head.next=null; head=temp; odd=odd.next; flag=!flag; } else{ even.next=head; ListNode temp = head.next; head.next=null; head=temp; even=even.next; flag=!flag; }} odd.next = evenhead.next; return oddhead.next; } }

链表模拟大数相加 【算法链表】链表头为高位的情况
代码描述
将链表反转,然后再与链表头是低位一样处理
将两个链表遍历完,如果为空则是0 不为空则相加 遍历完后
如果carry不等于0 则需要新建一个结点用来进位
/** * Definition for singly-linked list. * public class ListNode { *int val; *ListNode next; *ListNode(int x) { val = x; } * } */ class Solution { public ListNode addTwoNumbers(ListNode l1, ListNode l2) { l1=reverse(l1); l2=reverse(l2); int carry = 0; int sum = 0; ListNode head = new ListNode(0); ListNode cur= head; while(l1!=null||l2!=null){ int x = l1==null?0:l1.val; int y = l2==null?0:l2.val; sum = x+y+carry; cur.next = new ListNode(sum%10); cur=cur.next; carry = sum/10; l1=l1==null?null:l1.next; l2=l2==null?null:l2.next; }if(carry!=0) cur.next = new ListNode(carry); else cur.next = null; return reverse(head.next); }public ListNode reverse(ListNode l1){ if(l1==null||l1.next==null) return l1; ListNode head = reverse(l1.next); l1.next.next=l1; l1.next=null; return head; } }

复杂链表的复制 结点有两个指针一个是next 一个是random
代码分析
将链表
/* public class RandomListNode { int label; RandomListNode next = null; RandomListNode random = null; RandomListNode(int label) { this.label = label; } } */ public class Solution {public RandomListNode Clone(RandomListNode pHead) { if(pHead==null) return null; RandomListNode currentNode=pHead; while (currentNode!=null){ RandomListNode cloneNode=new RandomListNode( currentNode.label); RandomListNode temp=currentNode.next; currentNode.next=cloneNode; cloneNode.next=temp; currentNode=temp; } currentNode=pHead; while (currentNode!=null){ if (currentNode.random!=null){ currentNode.next.random=currentNode.random.next; } if(currentNode.random==null) currentNode.next.random=null; currentNode=currentNode.next.next; } currentNode = pHead; RandomListNode pCloneHead = pHead.next; while(currentNode != null) { RandomListNode cloneNode = currentNode.next; currentNode.next = cloneNode.next; cloneNode.next = cloneNode.next==null?null:cloneNode.next.next; currentNode = currentNode.next; }return pCloneHead; } }

    推荐阅读