一、链表中环的入口结点
描述
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,返回null。
输入描述:
输入分为2段,第一段是入环前的链表部分,第二段是链表环的部分,后台将这2个会组装成一个有环或者无环单链表
返回值描述:
返回链表的环的入口结点即可。而我们后台程序会打印这个节点
解题思路:
1.采用快慢指针进行求解
如果链表存在环,则fast和slow会在环内相遇,定义相遇点到入口点的距离为X,定义环的长度为C,定义头到入口的距离为L,fast在slow进入环之后一圈内追上slow,则会得知:
slow所走的步数为:L + X
fast所走的步数为:L + X + N * C
并且fast所走的步数为slow的两倍,故:
2*(L + X) = L + X + N * C
即: L = N * C - X
所以从相遇点开始slow继续走,让一个指针从头开始走,相遇点即为入口节点
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead) {
if(pHead==nullptr||pHead->next==nullptr)
return nullptr;
ListNode* slow=pHead;
ListNode* fast=pHead;
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast)
{
fast=pHead;
while(fast!=slow)
{
fast=fast->next;
slow=slow->next;
}
return fast;
}
}
return nullptr;
}
};
2.采用哈希进行求解
将链表中结点依次存入哈希中:如果该节点不存在则存入哈希中,如果存在相同结点,则证明该链表中有环,并且该节点为入口第一个节点。
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead) {
if(pHead==nullptr||pHead->next==nullptr)
return nullptr;
unordered_map<ListNode*,int> hash;
while(pHead->next)
{
if(hash.find(pHead)==hash.end())
{
hash[pHead]++;
}
else
{
return pHead;
}
pHead=pHead->next;
}
return nullptr;
}
};
二、括号序列
描述
给出一个仅包含字符'(',')','{','}','['和']',的字符串,判断给出的字符串是否是合法的括号序列
括号必须以正确的顺序关闭,"()"和"()[]{}"都是合法的括号序列,但"(]"和"([)]"不合法
class Solution {
public:
/**
*
* @param s string字符串
* @return bool布尔型
*/
bool isValid(string s) {
// write code here
stack<char> st;
for(auto& e:s)
{
if(e=='[')
st.push(']');
else if(e=='{')
st.push('}');
else if(e=='(')
st.push(')');
else
{
if(st.empty())
return false;
if(st.top()==e)
st.pop();
}
}
return st.empty();
}
};
三、删除链表的倒数第n个节点
描述
给定一个链表,删除链表的倒数第 nn 个节点并返回链表的头指针
例如,
给出的链表为: 1\to 2\to 3\to 4\to 51→2→3→4→5, n= 2n=2.
删除了链表的倒数第 nn 个节点之后,链表变为1\to 2\to 3\to 51→2→3→5.
备注:
题目保证 nn 一定是有效的
请给出时间复杂度为\ O(n) O(n) 的算法
class Solution {
public:
/**
*
* @param head ListNode类
* @param n int整型
* @return ListNode类
*/
ListNode* removeNthFromEnd(ListNode* head, int n) {
// write code here
if(!head||!head->next)
return nullptr;
ListNode*slow,*fast,*pre;
slow=fast=pre=head;
for(int i=0;i<n;i++)
{
fast=fast->next;
}
if(!fast)
return head->next;
while(fast)
{
pre=slow;
fast=fast->next;
slow=slow->next;
}
pre->next=slow->next;
delete slow;
return head;
}
};