• 力扣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
  • 相关阅读:
    SQL注入方法之:获取列名
    手把手教会你模拟退火算法
    我的G++编译选项
    编译器优化误解程序员的意思
    ZKW线段树
    扩展欧几里得算法
    快速幂
    乘法取模
    莫队算法良心讲解
    高精度模板
  • 原文地址:https://www.cnblogs.com/zhaojiayu/p/14496822.html
Copyright © 2020-2023  润新知