经典链表问题:解析链表中的关键挑战

这篇具有很好参考价值的文章主要介绍了经典链表问题:解析链表中的关键挑战。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

公共子节点

例如这样一道题:给定两个链表,找出它们的第一个公共节点。
经典链表问题:解析链表中的关键挑战,数据结构与算法,链表,数据结构,学习,java
具体的题目描述我们来看看牛客的一道题:
经典链表问题:解析链表中的关键挑战,数据结构与算法,链表,数据结构,学习,java
这里我们有四种解决办法:

采用集合或者哈希

思路是这样的,我们先把其中一个链表遍历放入Map中,然后遍历第二个第二个链表与Map中的对比,第一个相同的即为公共节点。

public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        Map<ListNode, Integer>  map = new HashMap<>();
        while (pHead1 != null) {
            map.put(pHead1, pHead1.val);
            pHead1 = pHead1.next;
        }
        while (pHead2 != null) {
            if (map.containsKey(pHead2)) {
                return pHead2;
            }
            pHead2 = pHead2.next;
        }
        return null;
    }

采用栈

这种方法,我们需要两个栈把两个链表分别遍历入栈,然后同时弹出,相同且最晚出栈的那一组即为公共节点。

public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        Stack<ListNode>  stack1 = new Stack<>();
        Stack<ListNode>  stack2 = new Stack<>();
        while (pHead1 != null) {
            stack1.push(pHead1);
            pHead1 = pHead1.next;
        }
        while (pHead2 != null) {
            stack2.push(pHead2);
            pHead2 = pHead2.next;
        }
        ListNode ret = null;
        while (stack1.size() > 0 && stack2.size() > 0) {
            if (stack1.peek() == stack2.peek()) {
                ret = stack1.pop();
                stack2.pop();
            } else {
                break;
            }

        }
        return ret;
    }

拼接两个字符串

先看下面的两个链表:
A:1-4-6-2-3-5
B:2-3-5
我们试着拼接一个
AB:1-4-6-2-3-5-2-3-5
BA:2-3-5-1-4-6-2-3-5
我们会发现链表只要有公共的节点,那么我们遍历AB与BA就会找到公共节点。

 public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        if (pHead1 == null || pHead2 == null) {
            return null;
        }
        ListNode p1 =  pHead1;
        ListNode p2 = pHead2;
        while (p1 != p2) {
            p1 = p1.next;
            p2 = p2.next;
            //防止陷入死循环
            if (p1 != p2) {
                if (p1 == null) {
                    p1 = pHead2;
                }
                if (p2 == null) {
                    p2 = pHead1;
                }
            }
        }
        return p1;
    }

差和双指针

遍历两个链表记录两个链表的长度,然后先遍历较长链表(len1-len2)绝对值个节点,然后两个链表同时向前走,节点一样的时候就是公共节点。

public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        if (pHead1 == null || pHead2 == null) {
            return null;
        }
        ListNode p1 = pHead1;
        ListNode p2 = pHead2;
        int len1 = 0, len2 = 0;
        while (p1 != null) {
            p1 = p1.next;
            len1++;
        }
        while (p2 != null) {
            p2 = p2.next;
            len2++;
        }
        int sub = Math.abs(len1 - len2);
        ListNode current1 = pHead1;
        ListNode current2 = pHead2;
        if (len1 > len2) {
            int a = 0;
            while (a < sub) {
                current1 = current1.next;
                a++;
            }
        }
        if (len2 > len1) {
            int a = 0;
            while (a < sub) {
                current2 = current2.next;
                a++;
            }

        }
        while (current1 != current2) {
            current1 = current1.next;
            current2 = current2.next;
        }
        return current2;
    }

这段代码是一个Java方法,用于查找两个链表中的第一个公共节点。方法名为FindFirstCommonNode,接收两个参数pHead1和pHead2,分别表示两个链表的头节点。
首先,判断两个链表是否为空,如果有一个为空,则返回null。
然后,使用两个指针p1和p2分别遍历两个链表,计算它们的长度len1和len2。
接下来,计算两个链表长度之差的绝对值sub。
再接着,创建两个新的指针current1和current2,分别指向两个链表的头节点。如果链表1的长度大于链表2的长度,将current1向后移动sub个节点;如果链表2的长度大于链表1的长度,将current2向后移动sub个节点。
最后,同时遍历两个链表,直到找到第一个相同的节点,将其返回。

旋转链表

我们有两种思路:文章来源地址https://www.toymoban.com/news/detail-734133.html

  • 将前k部分与N-k部分分别反转,连接起来就解决了。
  • 用双指针找到倒数K的位置,具体实现如下:
  public ListNode rotateRight(ListNode head, int k) {
     if(head==null || k==0){
         return head;
     }
     ListNode fast = head;
     ListNode slow = head;
     ListNode temp = head;
     int len = 0;
     while (head!=null){
         head = head.next;
         len++;
     }
     if(k%len==0){
         return temp;
     }
     while (k%len>0){
         k--;
         fast = fast.next;
     }
     while (fast.next!=null){
         fast = fast.next;
         slow = slow.next;
     }
     ListNode res = slow.next;
     fast.next = temp;
     slow.next=null;
return res;
    }
  1. 首先,判断链表是否为空或旋转位置数是否为0,如果满足任一条件,则直接返回原链表头节点。
  2. 初始化三个指针:fast、slow和temp,都指向链表头节点。同时,定义一个变量len用于记录链表的长度。
  3. 遍历链表,计算链表的长度。
  4. 判断旋转位置数k是否能被链表长度整除,如果能整除,则不需要旋转,直接返回原链表头节点。
  5. 如果旋转位置数k不能被链表长度整除,需要找到k对链表长度取模后的余数对应的节点位置。通过fast指针先向前移动k%len个位置,然后fast和slow指针同时向前移动,直到fast指针到达链表尾部。此时,slow指针所在的位置就是需要旋转后的新头节点。
  6. 将新头节点的下一个节点作为新链表的尾节点,将原链表的尾节点接到新链表的头部,形成新的链表。
  7. 返回新的链表头节点。

到了这里,关于经典链表问题:解析链表中的关键挑战的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 两两交换链表中的节点

     你存在,我深深的脑海里~ 这个题有点类似于反转一个单链表,不同的地方在于这个题不全反转,所以我们不同的地方在于此题多用了一个prve指针保存n1的前一个节点,以及头的改变,用newhead保存一个新的头,其他都大同小异,参考:反转一个单链表 个人主页:Lei宝啊 愿所

    2024年02月12日
    浏览(37)
  • 237. 删除链表中的节点

    将当前要删除的节点和后边一个的节点值交换,然后删除当前节点后边的一个节点即可。

    2024年02月16日
    浏览(38)
  • 【LeetCode热题100】【链表】两两交换链表中的节点

    题目链接:24. 两两交换链表中的节点 - 力扣(LeetCode) 实际上是两个两个一组颠倒顺序,可以用k=2使用【LeetCode热题100】【链表】K 个一组翻转链表-CSDN博客 但可以更简单,就先看两个,先取第二个的指针,递归颠倒第二个后面的节点,链接到第一个节点上,然后把第一个节

    2024年04月13日
    浏览(80)
  • 数据结构实验---顺序表的合并---链表的基本操作---重点解析约瑟夫问题

    实验的写法多种多样,但本文并未采用 #define 定义容量的写法,这样写已经是很老旧过时的写法。所有实验主体采用均为动态开辟,后续如果利用 C++ 来写或许会应用更多语法… 本篇展示数据结构的两个实验 其中,重点分析约瑟夫问题 实验中代码的命名风格等均与下方博客

    2024年02月16日
    浏览(62)
  • 24. 两两交换链表中的节点

    2024年02月07日
    浏览(46)
  • 数据结构(C语言):递归算法删除链表中所有值为x的结点

           这个标题为什么要叫“一个递归算法的诞生过程”呢?因为我在写这个算法的时候可谓一波三折,冲破重重Bug最终才得到了正确的算法。        所以在这里我和大家分享一下我写这段代码的整个过程。其中提到的一些问题大家可能写代码的时候也会遇到,所以建议

    2024年02月04日
    浏览(46)
  • 【LeetCode刷题-链表】--82.删除排序链表中的重复元素II

    由于链表是排好序的,所以只需要对其进行一次遍历即可,比较相邻节点对应的值

    2024年02月06日
    浏览(41)
  • LeetCode刷题---两两交换链表中的节点

    个人主页:元清加油_【C++】,【C语言】,【数据结构与算法】-CSDN博客 个人专栏:                   前言:这个专栏主要讲述递归递归、搜索与回溯算法,所以下面题目主要也是这些算法做的   我讲述题目会把讲解部分分为3个部分: 1、题目解析 2、算法原理思路讲解  3、

    2024年02月05日
    浏览(54)
  • 【算法题解】35. 两两交换链表中的节点

    这是一道 中等难度 的题 https://leetcode.cn/problems/swap-nodes-in-pairs/ 给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。 示例 1: 示例 2: 示例 3: 提示: 链表中节点的数目在范围

    2024年02月08日
    浏览(58)
  • leetcode-删除排序链表中的重复元素

    83. 删除排序链表中的重复元素 题解: 要删除一个已排序链表中的所有重复元素,从而使每个元素只出现一次,我们可以使用一个指针来遍历这个链表,同时比较当前节点和它下一个节点的值。如果它们相等,我们就删除下一个节点,如果不相等,我们就移动指针。 注:本题

    2024年02月02日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包