美文网首页
算法(5)- 链表一【翻转链表】

算法(5)- 链表一【翻转链表】

作者: 乄三楼半 | 来源:发表于2020-10-11 19:59 被阅读0次

说在前面:

1、链表不支持随机的访问元素,需从头一次遍历到要访问的节点。
2、思路
(1)设立头结点。
(2)借助辅助指针,修改节点的next指针实现。(穿针引线)
(3)删除当前节点,且前一节点未知时。可将后一节点的值赋给当前节点,再删除后一节点。
(4)不改变链表结构,通过修改节点值实现(一般不这样)
2、注意(1)与(2)的区别。

(1)ListNode cur = L1;
(2)ListNode cur = null;    cur.next = L1;

3、链表初始化及打印

       // 初始化head链表
        ListNode head = new ListNode(2);
        ListNode current = head;
        for (int j = 3; j < 10; j++) {
            current .next = new ListNode(j);
            current = current .next;
        }

      // 打印链表head
       ListNode resout = head;
        while (resout != null){
            System.out.println(resout.val);
            resout = resout.next;
        }
一、翻转链表例题
1. 206 翻转链表 Reverse Linked List

题目:反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
进阶:
你可以迭代或递归地反转链表。你能否用两种方法解决这道题?

  • 一般来说,链表相关不能只改变节点的值,而应该改变next指针实现。
    设立指针(引用)
题意.png 思路

(1)利用三个辅助指针,修改节点的next指针实现。

    public static ListNode reverseList(ListNode head) {
        /**
         *  利用三个辅助指针,修改节点的next指针实现。
         * 执行用时:0 ms, 在所有 Java 提交中击败了100.00% 的用户
         * 内存消耗:39.5 MB, 在所有 Java 提交中击败了5.06% 的用户
         */
        ListNode pre = head;
        ListNode cur = null;
        ListNode nex = null;
        if (pre != null){
            cur = head.next;
        }
        if (cur != null){
            nex = cur.next;
        }
        head.next = null;
        while (cur != null){
            cur.next = pre;
            pre = cur;
            cur = nex;
            if (nex != null){
                nex = nex.next;
            }
        }
        // ————测试输出节点
        ListNode resout = pre;
        while (resout != null){
            System.out.println(resout.val);
            resout = resout.next;
        }
        return resout;
}

(2) 通过修改节点的值实现翻转。

 /**
         *  通过修改节点的值实现翻转。辅助 HashMap 记录节点值,再反向赋给节点。
         * 执行用时:2 ms, 在所有 Java 提交中击败了5.09% 的用户
         * 内存消耗:39.3 MB, 在所有 Java 提交中击败了5.06% 的用户
         */
        Map<Integer, Integer> a = new HashMap<Integer, Integer>();
        int b = 0;
        // 用map记录节点的值
        ListNode cur = head;
        while (cur != null){
            a.put(b,cur.val);
            b++;
            cur = cur.next;
        }
        // 依次修改节点的值
        cur = head;
        while (cur !=null){
            cur.val = a.get(--b);
            cur = cur.next;
        }
        // 输出打印节点
        cur = head;
        while (cur!=null){
            System.out.println(cur.val);
            cur = cur.next;
        }
        return head;
C++解题示例
2. 92 反转链表II Reverse Linked List II ——比较复杂

题目
反转从位置 mn 的链表。请使用一趟扫描完成反转。
说明:1 ≤ mn ≤ 链表长度。
示例:
输入: 1->2->3->4->5->NULL, m = 2, n = 4
输出: 1->4->3->2->5->NULL

  • 本题借助五个“指针”,注意越界问题,及循环条件。
  • 注意特殊情况,如m=n,n=最后一个节点等等。
思路
 public static ListNode reverseBetween(ListNode head, int m, int n) {
        /**
         * 反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。
         * 1 ≤ m ≤ n ≤ 链表长度。
         * 执行用时:0 ms, 在所有 Java 提交中击败了100.00% 的用户
         * 内存消耗:37.4 MB, 在所有 Java 提交中击败了8.70% 的用户
         */
        if (m==n){
            return head;
        }
        ListNode pre = null;
        ListNode first = null;
        ListNode cur = head;   // 当前节点,与下面a相等
        ListNode nex = null;   // 下一节点,
        ListNode last = null;  // 下下节点,用于找到nex
        if (cur.next != null){
            nex = cur.next;
        }
        int a = 1;   
        // 当a属于[m,n]中,并且nex不为空,或者a = n(即n是最后一个节点时)
        while ((nex != null && a<n+1) || a==n){
            if (a==m-1){
                pre = cur;
                first = nex;
            }
            if (a<m){
                cur = nex;
                if (nex.next != null){
                    nex = nex.next;
                }
            }
            if (m==1){
                first = head;
                pre = head;
            }
            if (a>=m && a<n){
                // a>=m a<n 时,cur指针后移,nex指针后移,a++,nex指针
                last = nex.next;
                nex.next = cur;
                cur = nex;
                nex = last;
            }
            if (a == n){
                pre.next = cur;
                first.next = nex;
                if (m==1){
                    head = cur;
                }
            }
            a++;
        }
        return head;
    }
3. 328 奇偶链表

题目:给定一个单链表,把所有的奇数节点和偶数节点分别排在一起。请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性。
请尝试使用原地算法完成。你的算法的空间复杂度应为 O(1),时间复杂度应为 O(nodes),nodes 为节点总数。
示例 1:
输入: 1->2->3->4->5->NULL
输出: 1->3->5->2->4->NULL

算法思路:设置三个辅助指针,先找到奇数偶数节点的next指针,再将奇节点的最后一个指针指向偶数节点的第一个指针。

class Solution {
    public ListNode oddEvenList(ListNode head) {
        ListNode nowNode = head;
        ListNode secNode = null;
        ListNode nowSecNode = null;
        if(head == null){
            return head;
        }
        if(head.next != null){
            System.out.println("000000");
            secNode = head.next;    // 第二个节点
            nowSecNode = head.next; 
        }else{
            return head;
        }
// 先不管奇数最后一个指针,先排好两个链表。然后再连起来
        while(nowNode.next != null && nowNode.next.next != null){
            nowSecNode = nowNode.next;
            nowNode.next = nowSecNode.next;
            nowNode = nowSecNode.next;
            nowSecNode.next = nowNode.next;
        }
        nowNode.next = secNode;
        return head;
    }
}

相关文章

  • 算法(5)- 链表一【翻转链表】

    说在前面: 1、链表不支持随机的访问元素,需从头一次遍历到要访问的节点。2、思路(1)设立头结点。(2)借助辅助指...

  • 算法题面试复习

    算法模块 1. 链表 1. 链表翻转 2. 单链表判断是不是环+求环位置+求环长度 以图片为例,假设环入口距离链表...

  • 翻转链表算法

    翻转链表的方法有很多,如果是逆序输出链表,并且链表不是特别长的情况可以考虑直接用递归,以压栈的形式输出,然而,很多...

  • 【算法】翻转链表

    假设链表为 1→2→3→∅,我们想要把它改成∅←1←2←3。 在遍历链表时,将当前节点的指针改为指向前一个节点。由...

  • 一篇文章搞定面试中的链表题目(java实现)

    废话少说,上链表的数据结构 1.翻转链表 2.判断链表是否有环 3,链表排序 4.链表相加求和 5.得到链表倒数第...

  • 链表算法题集合(java实现)

    链表的数据结构 1.翻转链表 2.判断链表是否有环 3,链表排序 4.链表相加求和 5.得到链表倒数第n个节点 6...

  • 翻转链表

    翻转链表 描述翻转一个链表 样例给出一个链表1->2->3->null,这个翻转后的链表为3->2->1->nul...

  • 25. K 个一组翻转链表

    K个一组反转链表 翻转链表给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。 k 是一个正整数,它...

  • 链表

    1.翻转链表链表的定义 翻转 快慢指针找链表 的中间位置 3.有序链表的合并 4.判断链表中是否有环解法1: 借助...

  • 链表翻转

    给定单向链表,返回翻转后的链表

网友评论

      本文标题:算法(5)- 链表一【翻转链表】

      本文链接:https://www.haomeiwen.com/subject/iinicktx.html