3,165
社区成员




题目描述:
对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。
给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。
测试样例:
1->2->2->1
返回:true
题目链接:OJ链接
解题代码:
ListNode* findMid(ListNode* head)
{
struct ListNode* fast=head,*slow=head;
while(fast)
{
fast=fast->next->next;
slow=slow->next;
}
return slow;
}
ListNode* reverse(ListNode* mid)
{
ListNode* n1=NULL;
ListNode* n2=mid;
ListNode* n3=mid->next;
while(n2)
{
n2->next=n1;
n1=n2;
n2=n3;
if(n3)
{
n3=n3->next;
}
}
return n1;
}
class PalindromeList {
public:
bool chkPalindrome(ListNode* A) {
// write code her
//找中间节点
ListNode* mid=findMid(A);
//把中间节点后的节点逆置
ListNode* rmid=reverse(A);
while(A)
{
if(A->val!=rmid->val)
{
return false;
}
A=A->next;
rmid=rmid->next;
}
return true;
}
};
题目描述:
给你两个单链表的头节点 headA
和 headB
,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null
。
图示两个链表在节点 c1
开始相交:
https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2018/12/14/160_statement.png
https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2018/12/14/160_statement.png
题目数据 保证 整个链式结构中不存在环。
注意,函数返回结果后,链表必须 保持其原始结构 。
自定义评测:
评测系统 的输入如下(你设计的程序 不适用 此输入):
intersectVal
- 相交的起始节点的值。如果不存在相交节点,这一值为 0
listA
- 第一个链表 listB
- 第二个链表 skipA
- 在 listA
中(从头节点开始)跳到交叉节点的节点数 skipB
- 在 listB
中(从头节点开始)跳到交叉节点的节点数 评测系统将根据这些输入创建链式数据结构,并将两个头节点 headA
和 headB
传递给你的程序。如果程序能够正确返回相交节点,那么你的解决方案将被 视作正确答案 。
示例 1:
https://assets.leetcode.com/uploads/2018/12/13/160_example_1.png
https://assets.leetcode.com/uploads/2018/12/13/160_example_1.png
示例 2:
https://assets.leetcode.com/uploads/2018/12/13/160_example_2.png
https://assets.leetcode.com/uploads/2018/12/13/160_example_2.png
示例 3:
https://assets.leetcode.com/uploads/2018/12/13/160_example_3.png
https://assets.leetcode.com/uploads/2018/12/13/160_example_3.png
提示:
listA
中节点数目为 m
listB
中节点数目为 n
1 <= m, n <= 3 * 104
1 <= Node.val <= 105
0 <= skipA <= m
0 <= skipB <= n
listA
和 listB
没有交点,intersectVal
为 0
listA
和 listB
有交点,intersectVal == listA[skipA] == listB[skipB]
进阶:你能否设计一个时间复杂度 O(m + n)
、仅用 O(1)
内存的解决方案?
题目链接:OJ链接
解题代码:
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB)
{
struct ListNode *tailA=headA,*tailB=headB;
int lenA=0,lenB=0;
while(tailA->next)
{
lenA++;
tailA=tailA->next;
}
while(tailB->next)
{
lenB++;
tailB=tailB->next;
}
if(tailA!=tailB)
return NULL;
int gap=abs(lenA-lenB);//差距步
//假设A为长链表
struct ListNode *longList=headA,*shortList=headB;
if(lenA<lenB)
{
longList=headB;
shortList=headA;
}
while(gap--)
{
longList=longList->next;
}
while(longList)
{
if(longList==shortList)
return shortList;
longList=longList->next;
shortList=shortList->next;
}
return NULL;
}
题目描述:
给你一个长度为 n
的链表,每个节点包含一个额外增加的随机指针 random
,该指针可以指向链表中的任何节点或空节点。
构造这个链表的 深拷贝。 深拷贝应该正好由 n
个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next
指针和 random
指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点。
例如,如果原链表中有 X
和 Y
两个节点,其中 X.random --> Y
。那么在复制链表中对应的两个节点 x
和 y
,同样有 x.random --> y
。
返回复制链表的头节点。
用一个由 n
个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index]
表示:
val
:一个表示 Node.val
的整数。 random_index
:随机指针指向的节点索引(范围从 0
到 n-1
);如果不指向任何节点,则为 null
。 你的代码 只 接受原链表的头节点 head
作为传入参数。
示例 1:
输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
示例 2:
输入:head = [[1,1],[2,1]]
输出:[[1,1],[2,1]]
示例 3:
输入:head = [[3,null],[3,0],[3,null]]
输出:[[3,null],[3,0],[3,null]]
提示:
0 <= n <= 1000
-104 <= Node.val <= 104
Node.random
为 null
或指向链表中的节点。
题目链接:OJ链接
解题代码:
struct Node* copyRandomList(struct Node* head) {
struct Node* cur=head;
//将复制的链表先尾插到原链表的后面
while(cur)
{
struct Node* copy=(struct Node*)malloc(sizeof(struct Node));
copy->val=cur->val;
copy->next=cur->next;
cur->next=copy;
cur=copy->next;
}
//复制链表的random的指向
cur=head;
while(cur)
{
struct Node* copy=cur->next;
if(cur->random==NULL)
{
copy->random=NULL;
}else{
copy->random=cur->random->next;
}
cur=copy->next;
}
//将复制链表穿起来,并恢复原链表
struct Node* copyhead=NULL,*copytail=NULL;
cur=head;
while(cur)
{
struct Node* copy=cur->next;
struct Node* next=copy->next;
if(copyhead==NULL)
{
copyhead=copytail=copy;
}else{
copytail->next=copy;
copytail=copytail->next;
}
cur->next=next;//恢复原链表
cur=next;
}
return copyhead;
}
题目描述:
给你一个链表的头节点 head
,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next
指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos
不作为参数进行传递。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回 true
。 否则,返回 false
。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1
输出:false
解释:链表中没有环。
提示:
链表中节点的数目范围是
[0, 104]
-105 <= Node.val <= 105
pos
为 -1
或者链表中的一个 有效索引 。
进阶:你能用 O(1)
(即,常量)内存解决此问题吗?
题目链接:OJ链接
解题代码:
bool hasCycle(struct ListNode *head) {
struct ListNode* fast=head,*slow=head;
while(fast&&fast->next)
{
fast=fast->next->next;
slow=slow->next;
if(fast==slow)
{
return true;
}
}
return false;
}
题目描述:
给定一个链表的头节点 head
,返回链表开始入环的第一个节点。 如果链表无环,则返回 null
。
如果链表中有某个节点,可以通过连续跟踪 next
指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos
来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos
是 -1
,则在该链表中没有环。注意:pos
不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改链表。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1
输出:返回 null
解释:链表中没有环。
提示:
[0, 104]
内 -105 <= Node.val <= 105
pos
的值为 -1
或者链表中的一个有效索引 进阶:你是否可以使用 O(1)
空间解决此题?
题目链接:OJ链接
解题代码:
struct ListNode * hasCycle(struct ListNode *head) {
struct ListNode* fast=head,*slow=head;
while(fast&&fast->next)
{
fast=fast->next->next;
slow=slow->next;
if(fast==slow)
{
return fast;
}
}
return NULL;
}
struct ListNode *detectCycle(struct ListNode *head) {
if(hasCycle(head)==NULL)
{
return NULL;
}
else
{
struct ListNode* meet=hasCycle(head);
struct ListNode* cur=head;
while(cur)
{
if(cur==meet)
{
return cur;
}
cur=cur->next;
meet=meet->next;
}
}
return NULL;
}
文章来源: https://blog.csdn.net/2301_80221228/article/details/138504637
版权声明: 本文为博主原创文章,遵循CC 4.0 BY-SA 知识共享协议,转载请附上原文出处链接和本声明。