赞
踩
思路与算法
递归常用来解答链表和二叉树中的题目,在用递归时,牢记一点:递归的本质是反复调用自身,不要过度关系递归每一层的实现,只需要明白一级递归的过程即可。 写递归的套路(只需明白的三个地方): 1、递归什么时候结束? 2、递归的返回值是什么? 3、本级递归的目的是什么?(本级递归的操作是什么?) 本题中,题目要求我们两两交换链表中的节点,我们按照套路思考: 1、递归什么时候结束: 在只剩下一个节点或者没有节点的时候结束递归,因为只有一个节点时和没有节点时不需要再进行操作。 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* swapPairs(ListNode* head) {
- //递归牢记:不用管函数每一层做了是什么,只要知道第一层做了什么就行!
- //解题套路:1、找结束时的条件2、找递归返回值3、找当前这层执行什么
- //1、找结束条件:只有一个节点或者没节点的时候结束递归
- if(head==nullptr||head->next==nullptr)
- {
- return head;
- }
- //3、找当前执行语句:实现两个节点交换
- //下面的任务便是交换这3个节点中的前两个节点
- ListNode* second=head->next;//记录第二个节点,不然会找不到
- head->next=swapPairs(second->next);
- //头节点指向第三个节点,第三个节点是待处理的节点,它需要继续递归,传入的是它当前的头节点,即second->next
- second->next=head;
- //2、找返回值,返回的是当前这层递归结束后的头节点,这里是next
- return second;//返回second,因为此时的头节点已经变成了second
- }
- };
思路与算法
迭代法主要思路就是:通过循环两两交换节点
1、设置一个虚拟头节点dummary_head,并使dummary_head的next指向头节点,代码如下: ListNode* dummy_head=new ListNode(0); dummy_head->next=head;
2、如果直接对虚拟头节点进行操作的话,随着交换会使得交换后新的头节点位置不清除,所有需要设置一个操作节点,使其初始值和虚拟节点相同。 ListNode* cur=dummy_head;
3、通过循环进行节点交换,先考虑什么时候停止循环,当操作节点的下一个节点或下下个节点为空时,停止循环。如图所示:
4、判断返回类型,由于在交换时,虚拟头节点的位置不变,其next指向的永远是新的头节点,所以return dummy_head->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* swapPairs(ListNode* head) {
- ListNode* dummy_head=new ListNode(0);
- dummy_head->next=head;
- ListNode* cur=dummy_head;
- while(cur->next!=nullptr&&cur->next->next!=nullptr)
- {
- ListNode* temp=cur->next->next->next;
- ListNode* temp1=cur->next;
- cur->next=cur->next->next;
- cur->next->next=temp1;
- temp1->next=temp;
- cur=cur->next->next;
- }
- return dummy_head->next;
- }
- };
-
方法三:双指针
思路与算法
1、双指针法中,定义first和second两个节点,将first节点赋值为head,second节点的位置用于是first->next。 2、由于直接对first进行操作,因此first的位置一直在改变,无法确定新的头节点在哪,因此需要进行判断,如果链表中只有一个节点或链表中没有节点,直接return head; 3、只有当链表中节点大于等于2时,才能继续进行,否则在执行head=first->next;这一步操作会对空节点进行操作,语法错误。 4、通过循环进行节点交换,先考虑什么时候停止循环,当first节点或下个节点为空时,停止循环。如图所示:
- /**
- * 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* swapPairs(ListNode* head) {
- if(head==nullptr||head->next==nullptr) return head;
- ListNode* first=head;
- ListNode* temp=first;
- ListNode* second=nullptr;
- head=first->next;
- while(first!=nullptr&&first->next!=nullptr)
- {
- second=first->next;
- first->next=second->next;
- second->next=first;
- if(temp->next==second->next)
- {
- temp->next=second;
- }
- temp=first;
- first=first->next;
- }
- return head;
- }
- };
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。