指针必刷题
准备知识
题解
1)相交链表
题目描述:
解法一(暴力法):
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* ptrA=headA;
ListNode* ptrB=headB;
while(ptrA!=nullptr)
{
while(ptrB!=nullptr)
{
if(ptrA==ptrB)
{
return ptrA;
}
else ptrB=ptrB->next;
}
ptrB=headB;
ptrA=ptrA->next;
}
return nullptr;
}
};
解法二(巧妙解法):
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
//首先第一个想法,慢慢比对即可,即暴力法
//第二个想法,太巧妙了!!!编程如下,好好感受
//两条链分别为A、B,假设A为:a1、a2、a3、crosspoint、a4 B为:b1、b2、crosspoint、b3
//A+B:a1、a2、a3、crosspoint、a4、b1、b2、crosspoint、b3
//B+A:b1、b2、crosspoint、b3、a1、a2、a3、crosspoint、a4
// △△△
//可知当访问 A 链表的指针访问到链表尾部时,令它从链表 B 的头部开始访问链表 B;同样地,当访问
//B 链表的指针访问到链表尾部时,令它从链表 A 的头部开始访问链表 A。这样就能控制访问 A 和 B 两
//个链表的指针能同时访问到交点。
ListNode *L1=headA;
ListNode *L2=headB;
while(L1!=L2){
L1=(L1==nullptr)?headB:L1->next;
L2=(L2==nullptr)?headA:L2->next;
}
return L1;
}
};
2)链表反转
题目描述:
解法一:
一步步移动法,从第一个开始向后移动,将第一个移动到最后一个,然后将原来链表第二个移动到倒数第二个,依次类推
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* p1=head;
ListNode* p2=nullptr;
//一步步移动法,从第一个开始向后移动,将第一个移动到最后一个,然后将原来链表第二个移动到倒数第二个
//依次类推
while(p2!=head){
while(p1->next!=p2){
swap(p1,p1->next);
p1=p1->next;
}
p2=p1;
p1=head;
}
return head;
}
void swap(ListNode* L1,ListNode* L2){
int temp=L1->val;
L1->val=L2->val;
L2->val=temp;
}
};
时间复杂度O(n^2)。
解法二: