1.reverse-nodes-in-k-group(k组翻转链表)【hard】
给你一个链表以及一个k,将这个链表从头指针开始每k个翻转一下。链表元素个数不是k的倍数,最后剩余的不用翻转。
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ public class Solution { /** * @param head a ListNode * @param k an integer * @return a ListNode */ public ListNode reverseKGroup(ListNode head, int k) { // Write your code here if (head == null || k <= 1) { return head; } ListNode dummy = new ListNode(0); dummy.next = head; head = dummy; while (head.next != null) { head = reverseNextK(head, k); } return dummy.next; } private ListNode reverseNextK(ListNode head, int k) { ListNode node = head; for (int i = 0; i < k; i++) { if (node.next == null) { return head.next; } node = node.next; } ListNode n1 = head.next; ListNode prev = head; ListNode curt = head.next; for (int i = 0; i < k; i++) { ListNode temp = curt.next; curt.next = prev; prev = curt; curt = temp; } n1.next = curt; head.next = prev; return n1; } }
注意:n0->n1->n2->...->nk->nk+1若要翻转n1->...->nk,则n0到nk节点都会变化。 手动创建dummy node(哨兵节点),dummy.next总是head(头结点),最后返回dummy.next也即head节点。reverseNextK()函数分三步:1.检查是否有足够的k个节点可翻转(如果没有,返回head.next,因为此时的head节点实际已在上次操作中被翻转)2.翻转( n1 = head.next; prev = head; curt = head.next;for (int i = 0; i < k; i++) { temp = curt.next; curt.next = prev; prev = curt; curt = temp;})3.链接,以便继续下次翻转(n1.next = curt; head.next = prev; return n1;)
2.reverse-linked-list(翻转链表)
翻转一个链表。给出一个链表1->2->3->null,这个翻转后的链表为3->2->1->null。
/** * Definition for ListNode. * public class ListNode { * int val; * ListNode next; * ListNode(int val) { * this.val = val; * this.next = null; * } * } */ public class Solution { /** * @param head: The head of linked list. * @return: The new head of reversed linked list. */ public ListNode reverse(ListNode head) { // write your code here ListNode prev = null; ListNode curt = head; while (curt != null) { ListNode temp = curt.next; curt.next = prev; prev = curt; curt = temp; } return prev; } }
3.partition-list(链表划分)
给定一个单链表和数值x,划分链表使得所有小于x的节点排在大于等于x的节点之前。你应该保留两部分内链表节点原有的相对顺序。
/** * Definition for ListNode. * public class ListNode { * int val; * ListNode next; * ListNode(int val) { * this.val = val; * this.next = null; * } * } */ public class Solution { /** * @param head: The first node of linked list. * @param x: an integer * @return: a ListNode */ public ListNode partition(ListNode head, int x) { // write your code here if (head == null) { return head; } ListNode leftDummy = new ListNode(0); ListNode rightDummy = new ListNode(0); ListNode left = leftDummy; ListNode right = rightDummy; while (head != null) { if (head.val < x) { left.next = head; left = head; } else { right.next = head; right = head; } head = head.next; } left.next = rightDummy.next; right.next = null; return leftDummy.next; } }
注意:定义leftDummy和rightDummy两个哨兵节点,分别用来保存<x和≥x节点,最后进行链接即可。在left(right).next=head之后,left(right)也要=head。
4.merge-two-sorted-lists(合并两个排序链表)
将两个排序链表合并为一个新的排序链表。
/** * Definition for ListNode. * public class ListNode { * int val; * ListNode next; * ListNode(int val) { * this.val = val; * this.next = null; * } * } */ public class Solution { /** * @param ListNode l1 is the head of the linked list * @param ListNode l2 is the head of the linked list * @return: ListNode head of linked list */ public ListNode mergeTwoLists(ListNode l1, ListNode l2) { // write your code here ListNode dummy = new ListNode(0); ListNode head = dummy; while (l1 != null && l2 != null) { if (l1.val < l2.val) { head.next = l1; l1 = l1.next; } else { head.next = l2; l2 = l2.next; } head = head.next; } if (l1 != null) { head.next = l1; } else { head.next = l2; } return dummy.next; } }
注意:经典合并法。当两个链表都不为空时,比较节点值的大小...当其中一个链表不为空时...