1.链表相交
相交的定义是基于节点的引用,而不是简单的值。之前一直超出时间限制?判断它们是否相交并返回交点。采用双指针的方式,两个链表走过的长度是一样的,最后相遇在交点处。
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
if (headA == NULL || headB == NULL)
return NULL;
struct ListNode* La = headA,*Lb = headB;
while (La != Lb)
{
La = La == NULL ? headB : La->next;
Lb = Lb == NULL ? headA : Lb->next;
}
return La;
}
2.回文链表
链表反转的方法:https://blog.youkuaiyun.com/geekmanong/article/details/51097196。
ListNode* reverseList(ListNode * head){
if(head==NULL||head->next==NULL)
return head;
ListNode* pre=head, *cur=head->next, *temp=nullptr;
while(cur!=NULL){
temp=cur->next;
cur->next=pre;
pre=cur;
cur=temp;
}
head->next=NULL;
return pre;
}
解题思路:1,采用快慢两个指针去寻找链表的中间节点;
2,根据链表的中间节点反转后一半的链表;
3,迭代比较链表前一半的元素和后一半的元素,判断节点的值是否相等,得出是否为回文。
class Solution {
public:
bool isPalindrome(ListNode* head) {
if(head==NULL||head->next==NULL) return true;
ListNode *midnode=NULL, *halfnode=NULL;//halfnode是反转后的后一半的头结点
midnode=findmid(head);
halfnode=reverseList(midnode);
ListNode *h1=head, *h2=halfnode;
while(h2!=NULL){
if(h1->val!=h2->val) return false;
else{
h1=h1->next;
h2=h2->next;
}
}
return true;
}
private:ListNode* findmid(ListNode *head){
ListNode* slow=head, *fast=head;
while(fast!=NULL&&fast->next!=NULL){
slow=slow->next;
fast=fast->next->next;
}
return slow;
}
private:ListNode* reverseList(ListNode * head){
if(head==NULL||head->next==NULL)//链表为空的话返回的是NULL
return head;
ListNode* pre=head, *cur=head->next, *temp=nullptr;
while(cur!=NULL){
temp=cur->next;
cur->next=pre;
pre=cur;
cur=temp;
}
head->next=NULL;
return pre;
}
};
3.相交链表
找到两链表相交的起始节点。
方法一:哈希表法
方法二:双指针
和链表相交那道题目一样。
4.从尾到头打印链表
比较容易的想到了栈结构。
class Solution {
public:
vector<int> reversePrint(ListNode* head) {
stack<int> s;
vector<int> nums;
ListNode* p=head;
while(p!=NULL){
s.push(p->val);
p=p->next;
}
while(!s.empty()){
nums.push_back(s.top());
s.pop();
}
return nums;
}
};