1.相交链表
给你两个单链表的头节点
headA
和headB
,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回null
。图示两个链表在节点
c1
开始相交:题目数据 保证 整个链式结构中不存在环。
注意,函数返回结果后,链表必须 保持其原始结构 。
提示:
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]
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode ListNode;
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
//写法二(假设法)
ListNode* curA = headA;
ListNode* curB = headB;
int countA = 0;
int countB = 0;
while(curA->next)
{
curA = curA->next;
countA++;
}
while(curB->next)
{
curB = curB->next;
countB++;
}
//现在二者都指向尾节点,若他两不相等,则一定不相交'
if(curB!=curA)
{
return NULL;
}
//现在二者一定相交啦
//相对位置都在尾节点,差值也不会变
int sub = abs(countA-countB);
ListNode* longList = headA;
ListNode* shortList = headB;
//假设A是长链表,B是短的链表,不是的化再反转
if(countA < countB)
{
longList = headB;
shortList = headA;
}
//统一出发点
while(sub--)
{
longList = longList->next;
}
//现在二者一定相交,且出发点一致,一路到底找出交点
while(shortList != longList)
{
shortList = shortList ->next;
longList = longList->next;
}
return longList;
}
2.链表回文结构
对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。
给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。
测试样例:
1->2->2->1返回:true
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
typedef struct ListNode ListNode;
class PalindromeList {
public:
struct ListNode* reverseList(struct ListNode* head) {
ListNode* n1 = NULL;
if(head==NULL)
{
return head;
}
ListNode* n2 = head;
ListNode *n3 = head->next;
while(n2)
{
n2->next = n1;
n1 = n2;
n2 = n3;
if(n3)
{
n3 = n3->next;
}
}
return n1;
}
struct ListNode* middleNode(struct ListNode* head) {
ListNode *p1,*p2;
p1 = p2 = head;
while(p2&&p2->next)
{
p1 = p1->next;
p2 = p2->next->next;
}
return p1;
}
bool chkPalindrome(ListNode* A) {
// write code here
ListNode* mid = middleNode(A);
ListNode* rMid = reverseList(mid);
while(A&&rMid)
{
if(A->val!=rMid->val)
{
return false;
}
A = A ->next;
rMid = rMid ->next;
}
return true;
}
};
3.环形链表
给你一个链表的头节点
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
或者链表中的一个 有效索引 。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode ListNode;
bool hasCycle(struct ListNode *head) {
ListNode *slow = head,*fast = head;
//链表不为空且链表有多个节点
//若链表不存在环,则一定可以走到尽头
while(fast&&fast->next)
{
fast = fast->next->next;
slow = slow->next;
if(fast==slow)
{
return true;
}
}
return false;
}
4.环形链表2
给定一个链表的头节点
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
或者链表中的一个有效索引
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode ListNode;
struct ListNode *detectCycle(struct ListNode *head) {
ListNode *slow = head,*fast = head;
while(fast&&fast->next)
{
fast = fast->next->next;
slow = slow->next;
if(fast==slow)
{
ListNode* meet = slow;
while(meet!=head)
{
meet = meet->next;
head = head->next;
}
return meet;
}
}
return NULL;
}
标签:head,ListNode,struct,4.2,练习,next,链表,节点,leetcode From: https://blog.csdn.net/2301_80464369/article/details/137280257