代码随想录算法训练营第五天(周日休息)| LeetCode| C++| 206.反转链表 细究递归中的return问题 + 学习如何利用本地IDE进行debug(设置日志)

前言:
1、使用的本地IDE是Visual Studio 2022(下文简称VS)
2、VS的一些调试操作
Ctrl + Fn + F5 运行程序
Ctrl + Fn + F10 从main函数开始一步步执行(光标要先点到main函数那儿)
Fn + F10 每次执行一行语句,如果碰到函数调用,则把函数调用当成一条语句执行
Fn + F11 每次执行一行语句,如果碰到函数调用,则进入到函数内部一行行执行
Ctrl + Fn + F7 启动生成程序,看有几个错误
3、如何Debug?(摘自代码随想录算法训练营每日精华,内有更多干货,欢迎各位加入
在这里插入图片描述
本次调试采用2+3,在ChatGPT的基础上进行修改,得到自己想要的结果。不得不说,比自己想省事多了。

206.反转链表

正确代码如下:

class Solution {
public:
    ListNode* reverse(ListNode* cur, ListNode* pre){
        if(cur == NULL) return pre;
        ListNode* tmp = cur->next;
        cur->next = pre;
        //上面一次翻转已完成,于是进入下一次
        return reverse(tmp, cur);
    }
    ListNode* reverseList(ListNode* head) {
        return reverse(head, NULL);
    }
};

自己写的时候出现的问题:

return reverse(tmp, cur);

这一句代码没有加上return

先说结论:
若不加return,则无法将pre带到最外层出来。函数reverse()不断递归,进入最内层,满足了条件if(cur == NULL) return pre;后只有一个returnpre停留在倒数第二层。

Debug过程:
1、问一下ChatGPT:“这是我的代码,可以帮我修改一下实现可视化递归过程吗?” 然后就给了我一段代码,再自己修改一下。
2、学习了GPT链表的建立链表的打印,没我想得那么复杂hhh。
3、在相关的地方建个变量,每次进入递归或者从递归出来进行++再打印就行。我建了个全局变量int i = 1;并且用调试Fn + F10Fn + F11一步步看是怎么走的,就发现问题了。

GPT给的代码如下:

#include <iostream>
using namespace std;

struct ListNode {
	int val;
	ListNode* next;
	ListNode(int x) : val(x), next(NULL) {}
};

void printList(ListNode* head) {
	ListNode* curr = head;
	while (curr != NULL) {
		std::cout << curr->val << " ";
		curr = curr->next;
	}
	std::cout << std::endl;
}

ListNode* reverse(ListNode* cur, ListNode* pre) {

	if (cur == NULL) return pre;
	cout << "Reversing: ";
	printList(cur);
	ListNode* tmp = cur->next;
	cur->next = pre;	
	ListNode* newHead = reverse(tmp, cur);
	cout << "Returning newHead end: ";
	printList(newHead);
	return newHead;
}

ListNode* reverseList(ListNode* head) {
	cout << "Returning head: " << head->val << endl;
	return reverse(head, NULL);
}

int main() {
	ListNode* head = new ListNode(1);
	ListNode* node2 = new ListNode(2);
	ListNode* node3 = new ListNode(3);
	ListNode* node4 = new ListNode(4);
	ListNode* node5 = new ListNode(5);
	head->next = node2;
	node2->next = node3;
	node3->next = node4;
	node4->next = node5;
	// 反转链表 
	ListNode* newHead = reverseList(head);
	// 打印反转后的链表 
	std::cout << "Reversed list: ";
	printList(newHead);
	return 0;
}

我修改后的完整代码如下(没有写入return的):

#include <iostream>
using namespace std;

struct ListNode {
	int val;
	ListNode* next;
	ListNode(int x) : val(x), next(NULL) {}
};

void printList(ListNode* head) {
	ListNode* curr = head;
	while (curr != NULL) {
		std::cout << curr->val << " ";
		curr = curr->next;
	}
	std::cout << std::endl;
}

//建一个全局变量
int i = 1;
ListNode* reverse(ListNode* cur, ListNode* pre) {

	if (cur == NULL) return pre;
	cout << "Reversing: ";
	printList(cur);
	ListNode* tmp = cur->next;
	cur->next = pre;	
	//cout << "Returning newHead: ";
	//ListNode* newHead = reverse(tmp, cur);
	reverse(tmp, cur);
	cout << "开始返回第 " << i << "轮" << endl;
	i++;
	cout << endl;
	//cout << "Returning newHead end: ";
	//printList(newHead);
	//return newHead;
}

ListNode* reverseList(ListNode* head) {
	//cout << "Returning head: " << head->val << endl;
	return reverse(head, NULL);
}

int main() {
	ListNode* head = new ListNode(1);
	ListNode* node2 = new ListNode(2);
	ListNode* node3 = new ListNode(3);
	ListNode* node4 = new ListNode(4);
	ListNode* node5 = new ListNode(5);
	head->next = node2;
	node2->next = node3;
	node3->next = node4;
	node4->next = node5;
	// 反转链表 
	ListNode* newHead = reverseList(head);
	// 打印反转后的链表 
	std::cout << "Reversed list: ";
	printList(newHead);
	return 0;
}

结果如下:
在这里插入图片描述
可以看到递归进入到函数最内层后一层层返回(体现在i值的变化)。且没有return的情况下,最终的结果是错误的。原因就是没有把pre从最内层带到最外层。

这个过程中还发现了一个问题: 若把int i = 1建在函数reverse()里面,不管是放在递归之前还是递归之后,最终的结果都是每次碰到函数reverse()就会把i置为1,我也不知道为什么放在递归之后也会这样

return加回去结果就正常了,如下图所示:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值