【经典题目】链表OJ(轮转数组、返回倒数第k个节点、链表的回文结构)

小编主页详情<-请点击
小编gitee代码仓库<-请点击


本文主要介绍了有关链表的各种经典面试题目,内容全由作者原创(无AI),同时深度解析了题目的经典解决方法,并带有配图帮助博友们更好的理解,点个关注不迷路,下面进入正文~~


目录

1.轮转数组

2.返回倒数第k个节点

3.链表的回文结构

结语:


1.轮转数组

题目链接:轮转数组

方法1: 我们可以先保存数组的最后一个元素,然后将前n-1个元素向后挪一位。将这些操作重复k次,就能实现轮转数组。可当我们的K值比数组的元素还多的是时候,会出现重复轮转的操作。拿示例1举个例子:数组元素有7个,那么当k=3和k=10时有区别吗?显然没有区别。所以我们循环的次数可以是k%n次,这样有利于提高程序的运行效率。

那么当我提出这样的要求,该怎么做呢?

你可以用空间复杂度为 O(1)原地算法解决这个问题吗?

方法2: 这是一个比较巧妙的方法,名叫三段逆置 。具体布置如下图所示。

我们发现,三段逆置后就刚好是正确答案。具体代码如下

cs 复制代码
void reverse(int* nums, int n)
{
    int left = 0;
    int right = n - 1;
    while(left <= right)
    {
        int tmp = 0;
        tmp = nums[left];
        nums[left] = nums[right];
        nums[right] = tmp;
        left++;
        right--;
    }
}
void rotate(int* nums, int numsSize, int k) 
{
    int n = numsSize;
    k = k % n;
    reverse(nums,n);
    reverse(nums,k);
    reverse(nums + k,n - k);
}

2.返回倒数第k个节点

题目链接:返回倒数第k个节点

**思路1:**先找出链表的长度,减去k再遍历链表

**思路2:**逆置链表,再数第k个节点

思路3:快慢指针。我们可以让快指针先走k步,让快慢指针保持距离k,当快指针指向NULL时,慢指针刚好指向倒数第k个节点

详细代码如下:

cs 复制代码
int kthToLast(struct ListNode* head, int k) 
{
        struct ListNode* fast = head;
        struct ListNode* slow = head;

        while(k--)
        {
            fast = fast->next;
        }
        
        while(fast)
        {
            slow = slow->next;
            fast = fast->next;
        }

        return slow->val;
}

3.链表的回文结构

题目链接:链表的回文结构

这道题目,我们主要使用快慢指针链表逆序的方法

首先我们先使用快慢指针遍历一遍链表,慢指针一次走一步,快指针一次走两步。我们发现无论链表的节点是奇数还是偶数,当快指针遍历完数组时,慢指针刚好停在中间位置,且这个位置又恰好是回文链表前半节的最后一个节点,这个时候,我们尝试将中间节点后面的链表倒转

这里我们发现,mid往后的节点其实和头节点往后的节点是重合的。这里需要额外注意,虽然链表的后面逆置了,但是mid的前一个节点的指向并没有改变,这个节点仍然是指向他原来要指向的下一个节点。因此,我们可以再头节点和mid的节点同时向后遍历,如果出现数值不相同,就说明这个链表不是回文链表。当头节点或mid节点走到NULL时,说明已经遍历完了,这个链表就是回文链表。

下面是这道题目的完整代码

cs 复制代码
/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/

 
class PalindromeList {
public:
struct ListNode* reverseList(ListNode* head)
 {
    struct ListNode* cur = head;
    struct ListNode* next = NULL;
    struct ListNode* newnode = NULL;

    while(cur)
    {
        next = cur->next;
        //用next指针先保存下一个节点
        cur->next = newnode;
        //将当前节点的next指向新的头节点
        newnode = cur;
        //cur成为新的头节点
        cur = next;
        //将cur指向提前保存好的下一个节点
    }
    //此时链表已经成功逆置,newnode就我们需要的mid节点

    return newnode;
 }
    bool chkPalindrome(ListNode* A) 
    {
        // write code here
        struct ListNode* head = A;
        struct ListNode* slow = head;
        struct ListNode* fast = head;

        while(fast&&fast->next)
        {
            slow=slow->next;
            fast=fast->next->next;
        }
        //此时slow就是中间节点

    struct ListNode* mid = reverseList(slow);
    while(head && mid)
    {
        if(head->val!=mid->val)
        {
            return false;
        }
        head = head->next;
        mid = mid->next;
    }
    return true;
    }
};

结语:

这篇文章全文由作者手写,图片由画图软件所制,无AI制作,希望各位博友能有所收获

欢迎各位博友的讨论,觉得不错的小伙伴,别忘了点赞关注哦~

相关推荐
SteveSenna2 小时前
aubo i5+pika realsense+ACT训练完整流程
人工智能·学习·算法·机器人
Lyyaoo.2 小时前
【JAVA基础面经】CAS 与 ABA
java·开发语言
Allen_LVyingbo2 小时前
《狄拉克符号法50讲》习题与解析(上)
开发语言·人工智能·python·数学建模·量子计算
励志的小陈2 小时前
数据结构--堆(C语言实现)
android·c语言·数据结构
AC赳赳老秦2 小时前
OpenClaw对接百度指数:关键词热度分析,精准定位博客创作方向
java·python·算法·百度·dubbo·deepseek·openclaw
charlie1145141912 小时前
通用GUI编程技术——图形渲染实战(三十)——Direct2D几何体系统:从路径到命中测试
开发语言·c++·windows·信息可视化·c·图形渲染·win32
Ava的硅谷新视界2 小时前
SQLite WAL 模式踩坑笔记:高并发读写下的几个细节
开发语言·后端·编程
551只玄猫2 小时前
Why Financial Data Cannot Be Modeled with “Standard Machine Learning”
算法·机器学习·数学建模·金融·数据科学·英文·金融建模
小雅痞2 小时前
[Java][Leetcode middle] 274. H 指数
java·算法·leetcode