19. Remove Nth Node From End of List

题意:给一个链表,删除从尾数起的第n个结点,返回头节点。

我的思路

指针到最后,数出来有多少个,之从前向后数,再删掉节点

代码 10ms Beats 16.06%

class Solution {
public:ListNode* removeNthFromEnd(ListNode* head, int n) {ListNode * p=head;int sz=0;while(p!=NULL){cout<<p->val<<endl;p=p->next; sz++;   }p=head; int ta=sz-n;if(ta==0){head=p->next;delete p;p=NULL; return head;}for(int i=1;i<ta;i++)p=p->next;ListNode * q=p->next;p->next=q->next;delete q;p=q=NULL;return head;}
};

标答

双指针,类似追及问题的那种

第一个指针和第二个指针指向head,让第一个指针先跑n个结点,之后第一个指针和第二个指针一起跑,直到第一个指针跑到尾,这时第二个指针就是倒数第n个结点了,删除第二个指针指向的结点就可以了

注意第一个指针为空的情况单独讨论

代码 0ms Beats 100.00% 10.49mb Beats 99.85% 双指针

class Solution {
public:ListNode* removeNthFromEnd(ListNode* head, int n) {ListNode * fr=head;ListNode * se=head;for(int i=1;i<=n;i++)  fr=fr->next;if(fr==NULL){head=head->next;delete se; se=NULL;return head;}while(fr->next!=NULL){fr=fr->next;se=se->next;}fr=se->next; se->next=fr->next;delete fr;fr=NULL;return head;}
};

20. Valid Parentheses

题意:括号合法问题

我的思路

用栈看看合不合法

代码 0ms Beats 100.00% 6.40mb Beats 36.00% 栈

好像空间复杂度没办法在当前的时间复杂度下优化了

class Solution {
public:bool isValid(string s) {stack<char> st;for(int i=0;i<s.size();i++){if(s[i]==')'){if(st.empty())return 0;char a=st.top();st.pop();if(a!='(')return 0;}else if (s[i]==']'){if(st.empty())return 0;char a=st.top();st.pop();if(a!='[')return 0;}else if (s[i]=='}'){if(st.empty())return 0;char a=st.top();st.pop();if(a!='{')return 0;}else st.push(s[i]);}if(st.empty())return 1;return 0;}
};

21. Merge Two Sorted Lists

题意:把两个有序链表合成一个有序链表

我的思路

就直接合成

代码 3ms Beats 96.79% 14.72mb Beats 53.74%

class Solution {
public:ListNode* mergeTwoLists(ListNode* l, ListNode* r) {ListNode* ans=NULL;ListNode* m=ans;if(l!=NULL&&r==NULL){return l;}else if(l==NULL&&r!=NULL){return r;}else if(l==NULL&&r==NULL){return ans;}while(l!=NULL&&r!=NULL){if((l->val)<=(r->val)){if (m==NULL){ans=m=l;l=l->next;}else {m->next=l;m=m->next;l=l->next;}}else{if (m==NULL){ans=m=r;r=r->next;}else {m->next=r;m=m->next;r=r->next;}}}if(l!=NULL){m->next=l;}else if(r!=NULL){m->next=r;}return ans;}
};

22. Generate Parentheses

题意:给出括号数,生成所有可能性

我的思路 递归

递归,当右括号数用完的时候跳出递归,同时时刻注意左括号数一定要 大于等于 右括号数

代码 0ms Beats 100.00% 11.26mb Beats 91.80%

class Solution {
public:void solve(int n,int l,int r,vector<string> &ans,string &output){if(r==n){ans.push_back(output);return;}if(l>=r&&l<n){output.push_back('(');solve(n,l+1,r,ans,output);output.pop_back();}if(l>r){output.push_back(')');solve(n,l,r+1,ans,output);output.pop_back();}}vector<string> generateParenthesis(int n) {if(n==0) return {};int l=0,r=0;vector<string> ans;string output;solve(n,l,r,ans,output);return ans;}
};

标答 动态规划

看了看答案 除了递归 还有动态规划的做法,有点像矩阵连乘的动态规划

将问题看成重叠子问题,假设dp[i]包含所有长度为2*i的可能性,例如dp[2]为{ (()) , ()() },那么dp[3]可以被写成:

( + dp[0] + ) + dp[2] = ()(()),()()()
( + dp[1] + ) + dp[1] = (())()
( + dp[2] + ) + dp[0] = ((())),(()())

从上面可以看出,这是个重叠子问题结构(其个数为卡特兰数

状态转移函数为dp[i] = "(" + dp[j] + ")" + dp[i-j-1]

接下来从数据结构的角度来说,答案在dp[n]中,dp[n]是vector<string>,所以dp的数据结构是vector<vector<string>>,dp[left] 和 dp[right] 也是vector<string>

之后就可以写代码了 注意初始化怎么写!!!

代码 0ms Beats 100.00% 7.36mb Beats 97.26%

class Solution {
public:vector<string> generateParenthesis(int n) {vector< vector<string> > dp(n+1);//开辟空间dp[0]={""};//初始化for(int i=1;i<=n;i++){//动态规划中的nfor(int j=0;j<i;j++){//是状态转移方程中括号里的内容 也就是第几个左for(int l=0;l<dp[j].size();l++){for(int r=0;r<dp[i-j-1].size();r++){string output;output+="(";output+=dp[j][l];output+=")";output+=dp[i-j-1][r];dp[i].push_back(output);}}}}return dp[n];}
};

23. Merge k Sorted Lists

题意:你有一个链表组,排序成一个链表

我的思路

递归,两个两个合并,有种归并排序的意思,但是代码能不能写出来就不知道了呜呜呜;

还有注意链表为空的情况!想了想之前有两个链表排序的例子,不知道能不能用上

但是递归完后,合成的链表放在哪里呢?那就新开一个vector ans,把之前的list clear一下(?)

每个拿到手的list,如果到手的就一个内容return;到手是1个以上,分成【l, r/2】【r/2+1,r】每个函数返回的应该是一个链表,ans把上面两个返回量收集一下,之后合并函数,最后返回一个链表

不会写!!感觉就差一点,但已知runtime error 没办法了;只好写个顺序版的了呜呜呜

代码  115ms Beats 28.75% 12.85 MB 98.25%

class Solution {
public:ListNode* mergeTwoLists(ListNode* l, ListNode* r) {ListNode* ans=NULL;ListNode* m=ans;if(l!=NULL&&r==NULL){return l;}else if(l==NULL&&r!=NULL){return r;}else if(l==NULL&&r==NULL){return ans;}while(l!=NULL&&r!=NULL){if((l->val)<=(r->val)){if (m==NULL){ans=m=l;l=l->next;}else {m->next=l;m=m->next;l=l->next;}}else{if (m==NULL){ans=m=r;r=r->next;}else {m->next=r;m=m->next;r=r->next;}}}if(l!=NULL){m->next=l;}else if(r!=NULL){m->next=r;}return ans;}ListNode* mergeKLists(vector<ListNode*>& lists) {if (lists.size()==0){return NULL;}else if (lists.size()==1){return lists[0];}for(int i = 1; i < lists.size(); i++){lists[0] = mergeTwoLists(lists[0],lists[i]);}return lists[0];}
};

标答 是对半 但不是递归

首先先把[0, n-1],[1, n-2],[2, n-3],[3, n-4]…[n/2-1,n-n/2] 配对合并,把链表放在前者里面,之后合法长度变为(n+1)/2;

以上流程循环,直到n<=1;

代码 12ms Beats 99.55% 12.94mb Beats 92.23% 对半非递归

class Solution {
public:ListNode* mergeTwoLists(ListNode* l, ListNode* r) {ListNode* ans=NULL;ListNode* m=ans;if(l!=NULL&&r==NULL){return l;}else if(l==NULL&&r!=NULL){return r;}else if(l==NULL&&r==NULL){return ans;}while(l!=NULL&&r!=NULL){if((l->val)<=(r->val)){if (m==NULL){ans=m=l;l=l->next;}else {m->next=l;m=m->next;l=l->next;}}else{if (m==NULL){ans=m=r;r=r->next;}else {m->next=r;m=m->next;r=r->next;}}}if(l!=NULL){m->next=l;}else if(r!=NULL){m->next=r;}return ans;}ListNode* mergeKLists(vector<ListNode*>& lists){int n=lists.size();if(lists.size()==0) return NULL;while(n>1){for(int i=0;i<n/2;i++)lists[i] = mergeTwoLists(lists[i], lists[n-i-1]);n = (n+1)/2;}return lists.front();}};

标答 使用递归合并的

mergeTwoLists函数和mergeKLists函数都差不多,重点在于sol是怎么实现的?

哦哦对照了一下,好像是在递归的时候传参传错了

正确的应该是:

int mid=l+(r-l)/2;
        ListNode* a=sol(l,mid,lists);
        ListNode* b=sol(mid+1,r,lists);

我写的错误版本是:
        ListNode* a=sol(l,r/2,lists);
        ListNode* b=sol(r/2+1,r,lists);

为什么我写的是错误的呢?

假设lists的内容是0 1 2 3

0  1       2  3

00 11   21 23

会出现以上错误,也就是说,当l=2,r=3的时候会出现错误!!所以要用mid来解决

代码 12ms Beats 99.55% 12.94mb Beats 92.23%

class Solution {
public:ListNode* mergeTwoLists(ListNode* l, ListNode* r) {ListNode* ans=NULL;ListNode* m=ans;if(l!=NULL&&r==NULL){return l;}else if(l==NULL&&r!=NULL){return r;}else if(l==NULL&&r==NULL){return ans;}while(l!=NULL&&r!=NULL){if((l->val)<=(r->val)){if (m==NULL){ans=m=l;l=l->next;}else {m->next=l;m=m->next;l=l->next;}}else{if (m==NULL){ans=m=r;r=r->next;}else {m->next=r;m=m->next;r=r->next;}}}if(l!=NULL){m->next=l;}else if(r!=NULL){m->next=r;}return ans;}ListNode* sol(int l,int r,vector<ListNode*>& lists){if(l>=r)return lists[l];int mid=l+(r-l)/2;ListNode* a=sol(l,mid,lists);ListNode* b=sol(mid+1,r,lists);return mergeTwoLists(a,b);}ListNode* mergeKLists(vector<ListNode*>& lists) {if (lists.size()==0){return NULL;}return sol(0,lists.size()-1,lists);}
};

标答 优先队列

首先创建一个链表指针的优先队列q,接着把list的头指针都放进去,如果q是空的,那么就返回空;创建答案链表的头指针头指针指向当前堆顶的最小元素,把堆顶元素弹出,如果答案指针之后还有元素,那么就把答案指针的next放回堆中;

创建一个用于答案链表插入的尾指针,尾指针指向堆顶元素,堆顶元素弹出,尾指针指向next元素;如果尾指针next不为空,并放回堆中直到优先队列q空了,循环停止,这时答案链表也形成了。

代码 14ms Beats 99.29% 13.16mb Beats 82.20%

class Solution {
public:
struct compare {bool operator()(const ListNode* l, const ListNode* r) {return l->val > r->val;}
};
ListNode *mergeKLists(vector<ListNode *> &lists) { //priority_queuepriority_queue<ListNode *, vector<ListNode *>, compare> q;for(auto l : lists) {if(l)  q.push(l);}if(q.empty())  return NULL;ListNode* result = q.top();q.pop();if(result->next) q.push(result->next);ListNode* tail = result;            while(!q.empty()) {tail->next = q.top();q.pop();tail = tail->next;if(tail->next) q.push(tail->next);}return result;
}
};

!标答 直接输入的 但我应该学不会的

代码 5 ms Beats 99.82% 6.2 MB Beats 99.90%

int main()
{ios_base::sync_with_stdio(false);cin.tie(nullptr);ofstream out("user.out");vector<char> buf;constexpr size_t buf_size = 1e4;buf.resize(buf_size);out.rdbuf()->pubsetbuf(buf.data(), buf_size);vector<int> result;result.reserve(1e4);string in;while (getline(cin, in)){result.clear();for (size_t i = 0, s = size(in); i < s; ++i){const char c = in[i];const bool is_num = (c >= '0') && (c <= '9') || (c == '-');if (!is_num){continue;}else{char* off;result.push_back(strtol(&in[i], &off, 10));i += (off - &in[i]);}}sort(begin(result), end(result));out << '[';for (size_t i = 0, s = size(result); i < s; ++i) {if (0 != i)out << ',';out << result[i];}out << "]\n";}
}
#define main _
class Solution{
public:ListNode *mergeKLists(vector<ListNode *> &lists) { return nullptr; }
};

LeetCode Top100 Liked 题单(序号19~)相关推荐

  1. LeetCode Top100 Liked 题单(序号1~17)

    01Two Sum - LeetCode 我自己写的代码[193ms] 因为不知道怎么加cmp函数,就只能pair的first设为值了,但其实这也是瞎做,应该也是O(n²)吧 class Soluti ...

  2. 《LeetCode力扣练习》第19题 删除链表的倒数第 N 个结点 Java

    <LeetCode力扣练习>第19题 删除链表的倒数第 N 个结点 Java 一.资源 题目: 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点. 示例 1: 输入:hea ...

  3. Leetcode每日一题:171.excel-sheet-column-number(Excel表列序号)

    思路:就是168题的反命题,进制的方式完美解决: Leetcode每日一题:168.excel-sheet-column-title(Excel表名称) class Solution {public: ...

  4. LeetCode每日一题——792. 匹配子序列的单词数

    LeetCode每日一题系列 题目:792. 匹配子序列的单词数 难度:普通 文章目录 LeetCode每日一题系列 题目 示例 思路 题解 题目 给定字符串 s 和字符串数组 words, 返回 w ...

  5. 刷题汇总(三)leetcode 精选50题 C++答案总结

    题目来源 腾讯精选练习(50 题) 相关: 刷题汇总(一)leetcode 精选50题 JavaScript答案总结 刷题汇总(二)剑指Offer 66题 C++答案总结 刷题汇总(四)技术类编程题汇 ...

  6. 个人算法题精简导航整理(精炼汇总,含知识点、模板题、题单)

    文章目录 前言 导航 注意事项 技巧类 自定义Pair 排序 N维数组转一维 位运算 状态压缩 算法基础 枚举 √ 指数型枚举 排列型枚举 组合型枚举 左右区间枚举 模拟 √ 日期天数问题:平年闰年情 ...

  7. Leetcode每日一题——思路小记

    文章目录 LeetCode每日一题 golang T15 2020.6.12 三数之和,双指针的运用 T70 2020.6.13 斐波那契数列 T1014 2020.6.17 最佳观光:双指针,计算公 ...

  8. [kuangbin]各种各样的题单

    [kuangbin]各种各样的题单 专题1 简单搜索 POJ 1321 POJ 2251 POJ 3278 POJ 3279 POJ 1426 POJ 3126 POJ 3087 POJ 3414 F ...

  9. 设计链表(Leetcode第707题)

    此题涵盖了链表的常见操作,是练习链表操作非常好的一道题目 此题涵盖了链表的常见操作,是练习链表操作非常好的一道题目 此题涵盖了链表的常见操作,是练习链表操作非常好的一道题目 题目描述: 设计链表的实现 ...

最新文章

  1. 关于大型网站技术演进的思考(五)--存储的瓶颈(5)
  2. 64位win7安装vs2010出现“组件安装失败...”等问题的解决方法
  3. 不是“老赖”是“真还”!罗永浩 6 亿债务还了 4 亿
  4. oracle 11g ORA-12514
  5. 数据结构和算法学习一,开篇
  6. P2016 战略游戏
  7. java web 柱状图_使用JFreeChart实现基于Web的柱状图
  8. Html转快应用方法,卡片跳转快应用指定页面,如何点返回直接退出快应用回到卡片...
  9. VS2013显示行号及显示程序汇编代码
  10. 第二:Java+MyBatis(深入学习)
  11. mybatisplus service insert 空指针_c++ 图解层序遍历和逐层打印智能指针建造的二叉树...
  12. 下载devc++和codeblocks记录
  13. Android应用模块之间通信模式
  14. [3月25日]《编辑部的外传》
  15. 自动化测试ROI计算器
  16. AD统一查看元器件得封装信息
  17. Linux中使用cp命令报cp:omitting directory错误
  18. Qt之快速生成缩略图thumbnail
  19. 仁者乐山,智者乐水,吃货乐在北海道~
  20. 一种二值图像封闭孔洞的高效填充算法

热门文章

  1. 常见的报错内容以及解决方法(持续更新)
  2. python不支持的数据类型是什么
  3. A2-1 利用stb_image.h来进行图片的绘制与显示
  4. 计算智能——模糊控制Matlab实现
  5. Impossible 与 I’m possible
  6. 名词解释计算机辅助工程CAE,EDA名词解释大全
  7. mysql 快速复制数据库
  8. git to GitHub
  9. 性能魔方mmTrix:应用优质体验背后的护花使者
  10. sublime text _注册码