zoukankan      html  css  js  c++  java
  • 力扣206题、92题、25题(反转链表)

    206、反转链表

    基本思想:

    双指针迭代

    具体实现:

    1、申请两个指针,一个叫pre,一个叫cur

    cur代表的是当前节点,pre是cur的前一个节点

    刚开始,pre指向null,cur是第一个节点

    然后cur和pre共同往后走,

    cur每走完一步就要指向pre

    cur变成none了,就迭代完了

    2、cur如何往后走

    tmp记录cur当前节点的下一个节点

    tmp = cur.next

    cur = tmp

    代码:

    class Solution(object):
        def reverseList(self, head):
            """
            :type head: ListNode
            :rtype: ListNode
            """
            # 申请两个节点,pre和 cur,pre指向None
            pre = None
            cur = head
            # 遍历链表,while循环里面的内容其实可以写成一行
            # 这里只做演示,就不搞那么骚气的写法了
            while cur:
                # 记录当前节点的下一个节点
                tmp = cur.next
                # 然后将当前节点指向pre
                cur.next = pre
                # pre和cur节点都前进一位
                pre = cur
                cur = tmp
            return pre    
    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode() {}
     *     ListNode(int val) { this.val = val; }
     *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
     * }
     */
    class Solution {
        public ListNode reverseList(ListNode head) {
            ListNode prev = null;
            ListNode cur = head;
            ListNode temp = null;
            while (cur != null){
                temp = cur.next;
                cur.next = prev;
                prev = cur;
                cur = temp;
            }
            return prev;
        }
    }

    递归法

    1.递归参数以及返回值

    递归参数:前后指针

    返回值:新链表的头结点

    2.确认终止条件:

    cur指针(走的快的指针)指向null,递归终止

    3.单层递归逻辑

    和上一种方法的思想一致

    class Solution {
        public ListNode reverseList(ListNode head) {
            return reverse(null,head);
        }
        private ListNode reverse(ListNode prev, ListNode cur){
            if (cur == null){
                return prev;
            }
            ListNode temp = null;
           
            temp = cur.next;
            cur.next = prev;
            prev = cur;
            cur = temp;
           
            return reverse(prev, cur);
        }
    }

    92、反转链表的一部分

    基本思想:

    将需要反转的的地方先反转,

    然后与原来的链表拼接起来

    具体实现:

    left是需要反转的地方的第一个节点

    right是最后一个

    1、将pre放到left的前面一个节点

    2、将curr放到right后面一个节点

    3、切断连接

    4、将子链表反转,用单调的方式

    5、接回到原来的链表中

    代码:

    class Solution:
        def reverseBetween(self, head: ListNode, left: int, right: int) -> ListNode:
            def reverse_linked_list(head: ListNode):
                # 也可以使用递归反转一个链表
                pre = None
                cur = head
                while cur:
                    next = cur.next
                    cur.next = pre
                    pre = cur
                    cur = next
    
            # 因为头节点有可能发生变化,使用虚拟头节点可以避免复杂的分类讨论
            dummy_node = ListNode(-1)
            dummy_node.next = head
            pre = dummy_node
            # 第 1 步:从虚拟头节点走 left - 1 步,来到 left 节点的前一个节点
            # 建议写在 for 循环里,语义清晰
            for _ in range(left - 1):
                pre = pre.next
    
            # 第 2 步:从 pre 再走 right - left + 1 步,来到 right 节点
            right_node = pre
            for _ in range(right - left + 1):
                right_node = right_node.next
            # 第 3 步:切断出一个子链表(截取链表)
            left_node = pre.next
            curr = right_node.next
    
            # 注意:切断链接
            pre.next = None
            right_node.next = None
    
            # 第 4 步:同第 206 题,反转链表的子区间
            reverse_linked_list(left_node)
            # 第 5 步:接回到原来的链表中
            pre.next = right_node
            left_node.next = curr
            return dummy_node.next

     递归思想

    https://leetcode-cn.com/problems/reverse-linked-list-ii/solution/yi-bu-yi-bu-jiao-ni-ru-he-yong-di-gui-si-lowt/

    25、k个一组反转链表

    基本思想:

    递归+迭代

    1、递归:把前k个节点反转,后面的节点也是一条链表,

    而且规模比原来链表小,就是子问题

    子问题与原问题的结构相同

    2、迭代:同206题反转链表

    具体实现:

    1、先反转以head开头的k个元素

    2、将第k+1个元素作为head再递归调用

    3、将上述两个过程的结果连接起来

    就是反转完后的链表的尾结点连上下一次递归完后的新头节点

    反转完后的链表的尾结点是原链表的头结点

    代码:

    class Solution:
        def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
            if head is None:
                return None
            a = b = head
            for _ in range(k):
                if b is None:
                    return head
                b = b.next
            
            def reverse(a,b):
                pre = None
                cur = a
                next = a
                while cur != b:
                    next = cur.next
                    cur.next = pre
                    pre = cur
                    cur = next
                return pre
    
            newhead = reverse(a,b)
            a.next = self.reverseKGroup(b,k)
            return newhead
  • 相关阅读:
    手把手教你利用create-nuxt-app脚手架创建NuxtJS应用
    初识NuxtJS
    webpack打包Vue应用程序流程
    用选择器代替表格列的筛选功能
    Element-UI
    Spectral Bounds for Sparse PCA: Exact and Greedy Algorithms[贪婪算法选特征]
    Sparse Principal Component Analysis via Rotation and Truncation
    Generalized Power Method for Sparse Principal Component Analysis
    Sparse Principal Component Analysis via Regularized Low Rank Matrix Approximation(Adjusted Variance)
    Truncated Power Method for Sparse Eigenvalue Problems
  • 原文地址:https://www.cnblogs.com/zhaojiayu/p/14496822.html
Copyright © 2011-2022 走看看