①奇偶链表
数据规模:
思路:
整体思路不要想复杂了,就是活动next指针即可。重点收获在于——记住:链表和数组的重要差别是,链表没有下标的概念,也就是链表的访问虽然是顺序的,但是可以通过修改指针来更改既定的顺序!
代码:
/**
* 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 *oddEvenList(ListNode *head)
{
if (head == nullptr || head->next == nullptr || head->next->next == nullptr)
{
return head;
}
ListNode *res = head;
ListNode *nt = head->next;
ListNode *ou = head->next;
ListNode *ji = head;
ListNode *tmp = head;
int now = 0;
while (true)
{
++now;
head = tmp;
if (head == nullptr)
{
break;
}
if (now % 2 == 0)
{
tmp = head->next;
if(tmp == nullptr)
{
break;
}
ou->next = tmp->next;
ou = ou->next;
}
else
{
tmp = head->next;
if (tmp == nullptr)
{
break;
}
if(tmp->next == nullptr)
{
continue;
}
ji->next = tmp->next;
ji = ji->next;
}
}
ji->next = nt;
return res;
}
};
②相交链表
思路:
这个题这是第二遍做了,第一遍做的时候应该是参考了题解,但这次自己又给出了一个方法~~(感觉比题解好一些)~~ 。
题解思路:
用双指针的方法,用第一个指针F从listA开始遍历,用第二个指针P从listB开始遍历。
假设listA更短一些,则在F遍历完后,让F再从B开始遍历;同理对于P也是再从A开始遍历。
假设链表构造为下图:
则在F遍历到2的节点(即相交节点时),P也会遍历到2的节点,即当F与P相等时,说明找到了相交节点处。
可以这样想:A链 = A1 + C,B链 = B1 + C,其中C是公共部分。如果A、两链相交,则双指针在遍历完一次A1+B1+C后,一定会相遇,同理如果不想交,则C = NULL,在遍历完A1+B1后,两指针都指向空,返回任意指针也符合题意。
非常巧妙、且数学的做法!
个人思路:
用数据规模的偷工减料方法, 由于数据规模规定每一个节点的范围是1~1e5,则不妨先用F指针遍历A链,修改每一个节点的值,使之成为人为链表节点(也就是+1e5即可,因为自然链表的值不可能超过1e5,只有人为标记链表的值才会超过1e5),之后让P指针遍历B链,如果在遍历时,P指针指向的当前节点的值超过了1e5,说明之前被遍历过了,且这是相交节点的第一个节点,记录下来,然后重新遍历一遍A链,重新将值重置回来即可(再减去1e5),返回记录下来的地方(如果不相交,则指向空也结束了)
总而言之,个人思路较为取巧,题解思路更为巧妙,两者复杂度差别不大。
题解代码及最终结果:
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode * f = headA;
ListNode * p = headB;
while(f!=p)
{
if(f == nullptr)
{
f = headB;
}
else
{
f = f->next;
}
if(p == nullptr)
{
p = headA;
}
else
{
p = p->next;
}
}
return f;
}
};
个人代码:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode * f = headA;
while(f!=nullptr)
{
f->val += 100005;
f = f->next;
}
ListNode * p = headB;
while(p!=nullptr)
{
if(p->val >= 100005)
{
break;
}
p = p->next;
}
f = headA;
while(f!=nullptr)
{
f->val -= 100005;
f = f->next;
}
return p;
}