目录
刷题日期:21:3404 星期五2021年3月12日
个人刷题记录,代码收集,来源皆为leetcode
主要答题语言为C++
题目:
剑指 Offer 06. 从尾到头打印链表
难度简单108收藏分享切换为英文接收动态反馈
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
示例 1:
输入:head = [1,3,2]
输出:[2,3,1]
限制:
0 <= 链表长度 <= 10000
初始解答:
第一次接触栈和实战列表,参考了书本。字符串的处理基本功还很差,参考了书本。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
vector<int> reversePrint(ListNode* head) {
// std::stack<ListNode* head>nodes;
// ListNode* pNode = head;
const ListNode* pNode = head;
std::size_t count = 0;
while(pNode!=NULL){
head.push(pNode);
pNode = pNode->next;
}
int rehead[head.length],i=0;
while(!head.empty()){
rehead[i] = head.top();
i++;
head.pop();
}
return rehead;
}
};
书本上用栈的方法各种错,调试了一会还是放弃了。两道题的要求不同,leetcode要求返回数组形式的结果,而书本上只是打印出来,还得想办法设置数组存储变量。也没有理解题目的val等量是啥意思,使用了下面的方法一,学习代码,加上相应的注释
学习他人:
小小小薯条🍟发布于 9 天前229 C++
方法一:| 递归
递归需要设定新变量。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {} //这一句并没有理解多了有什么用
* };
*/
class Solution {
public:
vector<int> ans;
vector<int> reversePrint(ListNode* head) {
// vector : C++ STL中的顺序容器,封装数组
// 与其他容器不同,其内存空间只会增长,不会减小。
recur(head);
return ans;
}
void recur(ListNode* head) { //输入的还是头节点
if (head == nullptr) return; //为空则直接结束
recur(head->next); //递归调用了recur,指向链表的下一项
// ans.emplace_back(head->val);
//该函数是 C++ 11 新增加的,其功能和 push_back() 相同,
// 都是在 vector 容器的尾部添加一个元素。
//刚好是反向添加,所以满足了要求
ans.push_back(head->val); //貌似也可以,看别人博客评论还是有区别的
}
};
方法二:| 栈
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {} //这一句并没有理解多了有什么用
* };
*/
class Solution {
public:
vector<int> reversePrint(ListNode* head) {
stack<int> st; //c++ stl默认构造函数,创建一个空的 stack 栈容器对象。
vector<int> ans;
/*
向量(Vector)
是一个封装了动态大小数组的顺序容器(Sequence Container)。
跟任意其它类型容器一样,它能够存放各种类型的对象。
可以简单的认为,向量是一个能够存放任意类型的动态数组。
*/
while (head) {
st.push(head->val); //观察代码,val是指链表的数据部分,推入栈中
head = head->next;
}
while (!st.empty()) { //只要栈内还有元素,循环继续
ans.emplace_back(st.top()); //栈顶元素赋给数组
st.pop(); //出栈操作
}
return ans;
}
};
其他区别
python代码有stack.append()
函数, java 则有stack.addLast()、stack.removeLast()
函数,注意区别,详细可参考精选题解。
教材示例代码
书里的版本先设置了一个bool型参数found,我也参考了这个意见。不过对比发现leetcode上的版本和书里的问题初始设置的代码并不相同。
void PrintListReversingly_Iteratively(ListNode* pHead)
{
std::stack<ListNode*> nodes;
ListNode* pNode = pHead;
while(pNode != nullptr)
{
nodes.push(pNode);
pNode = pNode->m_pNext;
}
while(!nodes.empty())
{
pNode = nodes.top();
printf("%d\t", pNode->m_nValue);
nodes.pop();
}
}
void PrintListReversingly_Recursively(ListNode* pHead)
{
if(pHead != nullptr)
{
if (pHead->m_pNext != nullptr)
{
PrintListReversingly_Recursively(pHead->m_pNext);
}
printf("%d\t", pHead->m_nValue);
}
}
看完之后再看这段代码,妥妥的裹脚布。
冒泡
这部分是下午时看数据结构时自己照着思路摸索出来的,可以直接在文件中跑通,平时这种模块化的代码题做多了,也不能忘了自己编一整个程序,今天就遇到了很多低级错误。
例如数组的定义啦、cout后的括号方向啦等等,需要注意。
// 冒泡排序算法,参考2021版数据结构高分笔记
#include <iostream>
using namespace std;
void BubbleSort(int R[],int n){
int i,j,flag,temp;
for(i = n-1;i>=1;--i){
flag = 0;
for(j = 1;j<=i;++j){
if(R[j-1]>R[j]){
temp = R[j-1];
R[j-1] = R[j];
R[j] = temp;
flag = 1;
}
}
}
if(flag == 0)
for(i = 0;i<10;++i)
cout<<R[i]<<',';
return;
}
int main()
{
int test[10] = {49,38,65,9,76,13,27,49,23};
BubbleSort(test,10);
return 0;
}
总结
以上就是本题的内容和学习过程了,基本上根据题目需要倒序,自然要想到栈、另外递归往往是基于栈,建立思路即可。
欢迎讨论,共同进步。