leetcode刷题之链表之递归

206.反转链表


主要有两种解法,双指针迭代和递归方法

1.双指针迭代法

public ListNode reverseList(ListNode head) {
 			ListNode pre=null;
 			ListNode cur=head;//cur一开始赋值为头节点
 			ListNode tmp=null;//该变量负责保存cur的下一个节点,起暂存储功能
 			while(cur!=null) {
 				tmp=cur.next;
 				cur.next=pre;//cur调转指针方向,转向pre,也就是反转链表方向
 				pre=cur;
 				cur=tmp;//上面这两行代码其实相当于把pre和cur同时前进一步
 			}
 			//整个循环相当于重复将cur所指方向进行反转,同时cur不断向前行进
 			return pre;
 			/*注意,cur在上面循环里会一直走到链表的最终节点
 			*所以最后cur跳出循环时是等于null,而pre此时为链表的最终节点*/
 		}

思路简述

设置两个指针,第一个指针叫 pre,最初是指向 null 的。
第二个指针 cur 指向 head,然后不断遍历 cur。
同时设置一个指针tmp用来保存cur的下一个节点。
每次迭代到 cur,都将 cur 的 next 指向 pre,然后 pre 和 cur 前进一位。
都迭代完了(cur 变成 null 了),pre 就是最后一个节点了。

2.递归方法

理解递归法的关键就是要理解栈是怎样野蛮生长的,函数调用,函数返回在栈里是怎样进行的

public ListNode reverseList1(ListNode head) {
	if(head==null||head.next==null) {
		return head;
	}
	ListNode cur=reverseList1(head.next);
	head.next.next=head;
	head.next=null;
	return cur;
}

思路简述

关键几点,当一个被调用函数a5遇到retrun head,要销毁栈帧的时候,最后会执行pop eip操作,也就是将代码段的eip指针指向调用a5函数的b4函数的下一条指令。
LIstNode cur=reverseList(head.next)其实是两条指令,第一条是调用函数reverseList,第二条是将reverseList返回值赋值给cur。
也就是说,当a5被调用完毕时,下一步操作就是对cur进行赋值。然后依次执行b4里ListNode cur=reverseList1(head.next);的下面几条指令,⚠️,此时b4里的head是4!直到遇到return cur,此时,b4为被调用函数,c3为调用函数,此时c3里的head是3。
重复上面的操作,简称套娃。
可以看出,cur始终保持不变,指向最后一个节点。

函数调用主要步骤

在函数a调用一个函数b的时候,重要的几个步骤:
一、开始时
1.函数b参数从左至右入栈
2.push eip (将下一条指令入栈保存起来,同时esp指针下移
3.push ebp (将函数a的基指针入栈保存)
4.mov ebp esp (将esp的值存入ebp,也就是将ebp指向esp,同时下移esp指针)
5.push ebx 、push esi 、push edi;然后进行中间的
二、返回时
1.pop edi、 pop esi、pop ebx;
2.mov esp ebp; (将ebp的值给esp,也就是将esp指向ebp,销毁b函数的函数栈帧
3.pop ebp;
4.ret (这一条指令相当于pop eip ;也就是说eip将指向原来保存的下一条指令
5.add esp 8;(此时如果传入b函数的参数已经不需要了,那么此时将esp指针上移,抬升栈帧,保持堆栈平衡。)

21.合并两个链表

public ListNode mergetwoLists(ListNode l1,ListNode l2) {
	if(l1==null) {
		return l2;
	}
	else if(l2==null) {
		return l1;
	}
	else if(l1.val<l2.val) {
		l1.next=mergetwoLists(l1.next,l2);
		return l1;
	}
	else  {
		l2.next=mergetwoLists(l2.next,l1);
		return l2;
	}	
}

思路简述

终止条件:当两个链表都为空时,表示我们对链表已合并完成。
如何递归:我们判断 l1 和 l2 头结点哪个更小,然后较小结点的 next 指针指向其余结点的合并结果。(调用递归)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值