本文主要介绍了有关链表的各种经典面试题目,内容全由作者原创(无AI),同时深度解析了题目的经典解决方法,并带有配图帮助博友们更好的理解,点个关注不迷路,下面进入正文~~
目录
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制作,希望各位博友能有所收获
欢迎各位博友的讨论,觉得不错的小伙伴,别忘了点赞关注哦~
