1. 删除排序链表的重复元素, 使得每个元素只出现一次
// leetcode 83class Solution { public ListNode deleteDuplicates(ListNode head) { if(head == null){ return null; } 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; }}
2. 删除排序链表所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字
//leetcode 82
class Solution { public ListNode deleteDuplicates(ListNode head) { if(head == null){ return head; } ListNode dummyNode = new ListNode(0, head); ListNode pre = dummyNode; ListNode cur = head; while(cur!=null){ ListNode diff = cur; int sameNum = 0; //从当前节点开始,遍历和当前节点相同的节点个数 while(diff!=null && diff.val == cur.val){ sameNum++; diff = diff.next; } if(sameNum>1){ pre.next = diff; }else{ pre = cur; } cur = diff; } return dummyNode.next; }}
3. 反转一个单链表
// leetcode 206
//方法一:迭代
class Solution { public ListNode reverseList(ListNode head) { if(head==null){ return head; } ListNode pre = null; ListNode cur = head; while(cur!=null){ ListNode temp = cur.next; cur.next = pre; pre = cur; cur = temp; } return pre; }}
//方法二:递归
class Solution { public ListNode reverseList(ListNode head) { if(head==null || head.next == null){ return head; } ListNode new_head = reverseList(head.next); head.next.next = head; head.next = null; return new_head; }}
4. 反转从位置m到n的链表
// leetcode 90
// pre 一直指向需要left的前一个节点,cur一直指向left的那个节点,一直将cur后面的节点插入到pre的后面
class Solution { public ListNode reverseBetween(ListNode head, int left, int right) { ListNode dummy_node = new ListNode(-1,head); ListNode cur = head; ListNode pre = dummy_node; int index = 1; while(index < left){ index ++; pre = cur; cur = cur.next; } while(index<right){ ListNode temp = cur.next; cur.next = temp.next; temp.next = pre.next; pre.next = temp; index ++; } return dummy_node.next; }}
5. 合并两个有序链表
// leetcode 21
// 方法一:递归
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; } }}
//方法二:迭代
class Solution { public ListNode mergeTwoLists(ListNode l1, ListNode l2) { ListNode pre_none = new ListNode(); ListNode pre = pre_none; while(l1!=null && l2!=null){ if(l1.val<l2.val){ pre.next = l1; l1 = l1.next; }else{ pre.next = l2; l2 = l2.next; } pre = pre.next; } // 最后肯定有一个为空,另一个不为空 if(l1 == null){ pre.next = l2; }else{ pre.next = l1; } return pre_none.next; }}
6. 分隔链表
// leetcode 86class Solution { public ListNode partition(ListNode head, int x) { ListNode small_node = new ListNode(-1,head); ListNode large_node = new ListNode(-1,head); ListNode small_head = small_node; ListNode large_head = large_node; ListNode cur = head; while(cur!=null){ if(cur.val<x){ small_head.next = cur; small_head = small_head.next; }else{ large_head.next = cur; large_head = large_head.next; } cur = cur.next; } large_head.next = null; small_head.next = large_node.next; return small_node.next; }}
7. 排序列表
// leetcode 148
//方法一: 递归-自顶向下归并排序
class Solution { public ListNode sortList(ListNode head) { return sortList(head,null); } public ListNode sortList(ListNode head,ListNode tail){ if(head == null){ return null; } if(head.next == tail){ head.next = null; return head; } ListNode slow = head; ListNode fast = head; while(fast != tail){ slow = slow.next; fast = fast.next; if(fast != tail){ fast = fast.next; } } ListNode mid = slow; ListNode list1 = sortList(head,mid); ListNode list2 = sortList(mid,tail); ListNode sorted = merge(list1, list2); return sorted; } public ListNode merge(ListNode l1, ListNode l2){ ListNode dummy_node = new ListNode(-1); ListNode pre = dummy_node; while(l1!=null && l2!=null){ if(l1.val < l2.val){ pre.next = l1; l1 = l1.next; }else{ pre.next = l2; l2 = l2.next; } pre = pre.next; } if(l1==null){ pre.next = l2; }else{ pre.next = l1; } return dummy_node.next; }}
//方法二-自底向上归并迭代
8. 重排链表
// leetcode 143
//方法一:线性表class Solution { public void reorderList(ListNode head) { List<ListNode> list = new ArrayList<>(); ListNode node = head; while(node!=null){ list.add(node); node = node.next; } int size = list.size(); int i = 0; int j = size-1; while(i<j){ list.get(i).next = list.get(j); i++; list.get(j).next = list.get(i); j--; } list.get(i).next = null; }}
//方法二:
class Solution { public void reorderList(ListNode head) { if(head == null){ return; }
// 选择中间节点,把list截成两段,翻转后面的那一段,然后再合并 ListNode mid = midNode(head); ListNode l1 = head; ListNode l2 = mid.next; mid.next = null; l2 = reverse(l2); merge(l1,l2); } public ListNode midNode(ListNode head){ ListNode slow = head; ListNode fast = head; while(fast!=null && fast.next!=null && fast.next.next!=null){ slow = slow.next; fast = fast.next.next; } return slow; } public ListNode reverse(ListNode head){ ListNode pre = null; ListNode cur = head; while(cur!=null){ ListNode temp = cur.next; cur.next = pre; pre = cur; cur = temp; } return pre; } public void merge(ListNode l1, ListNode l2){ ListNode l1_tmp ; ListNode l2_tmp ; while(l1!=null && l2!=null){ l1_tmp = l1.next; l2_tmp = l2.next; l1.next = l2; l1 = l1_tmp; l2.next = l1; l2 = l2_tmp; } } }
9. 环形链表
// leetcode 142
// 方法一:用一个set
public class Solution { public ListNode detectCycle(ListNode head) { Set<ListNode> set = new HashSet<>(); ListNode cur = head; while(cur!=null){ if(set.contains(cur)){ return cur; } set.add(cur); cur = cur.next; } return null; }}
//方法二:快慢指针
10. 复制带随机指针的链表
// leetcode 138 图解的方法三class Solution { public Node copyRandomList(Node head) { if(head==null){ return null; } Node cur = head; while(cur != null){ // 复制出来A->A'->B->B'->C->C',此时的A',B',C'的random指针是空 Node temp = new Node(cur.val); temp.next = cur.next; cur.next = temp; cur = temp.next; } Node old_head = head; Node new_head = head.next; Node old_cur = old_head; while(old_cur!=null){//给random指针赋值,A'的random=A的random的next Node random = old_cur.random; if(random == null){ old_cur.next.random = null; }else{ old_cur.next.random = random.next; } old_cur = old_cur.next.next; } Node cur_1 = old_head;//截断成两个链表A->B->C 和A'->B'->C' Node cur_2 = new_head; while(cur_2!=null){ if(cur_2.next==null){ cur_1.next = null; }else{ cur_1.next = cur_2.next; cur_2.next = cur_2.next.next; } cur_1 = cur_1.next; cur_2 = cur_2.next; } return new_head; }}