Chapter six Linked List & Array(链表与数组)

Posted struggleforit

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Chapter six Linked List & Array(链表与数组)相关的知识,希望对你有一定的参考价值。

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;
    }
}
View Code

注意: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;
    }
}
View Code

 

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;
    }
}
View Code

注意:定义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;
    }
}
View Code

注意:经典合并法。当两个链表都不为空时,比较节点值的大小...当其中一个链表不为空时...

 

以上是关于Chapter six Linked List & Array(链表与数组)的主要内容,如果未能解决你的问题,请参考以下文章

the art of seo(chapter six)

Chapter Six:常用的编码与加密介绍(python和js实现)

Jan 23 - Reverse Linked List; Linked List; Pointers;

[Algorithm] 234. Palindrome Linked List / Reverse linked list

Linked List-237. Delete Node in a Linked List

LeetCode2.Linked List — Linked List Cycle II 链表环2