21. 合并两个有序链表

难度简单1259

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

示例:

输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4

class Solution {
public:ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {ListNode* l3=new ListNode(0);//哑结点ListNode* ans=l3;while(l1||l2){if(l1&&l2){if(l1->val<=l2->val){l3->next =l1; l1=l1->next;}else{l3->next= l2;l2=l2->next;}l3=l3->next;}else if(l1){l3->next=l1;l1=NULL;}else{l3->next=l2;l2=NULL;}// l3=l3->next;}return ans->next;}
};

22. 括号生成

难度中等1292

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

示例:

输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]

回溯法,这题还可以用动态规划做啊....

    vector<string> generateParenthesis(int n) {vector<string> res;get(n,0,0,"",res);return res;}void get(int n,int r,int l,string a,vector<string> &res){if(r>n||l>n||l>r) return;if(r==n&&l==n){res.push_back(a);return;}get(n,r+1,l,a+"(",res);get(n,r,l+1,a+")",res);}

23. 合并K个升序链表

难度困难898

给你一个链表数组,每个链表都已经按升序排列。

请你将所有链表合并到一个升序链表中,返回合并后的链表。

示例 1:

输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[1->4->5,1->3->4,2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6

示例 2:

输入:lists = []
输出:[]

示例 3:

输入:lists = [[]]
输出:[]

顺序合并、分治合并、优先队列

/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode(int x) { val = x; }* }*/
class Solution {public ListNode mergeKLists(ListNode[] lists) {if (lists == null || lists.length == 0) return null;return merge(lists, 0, lists.length - 1);}private ListNode merge(ListNode[] lists, int left, int right) {if (left == right) return lists[left];int mid = left + (right - left) / 2;ListNode l1 = merge(lists, left, mid);ListNode l2 = merge(lists, mid + 1, right);return mergeTwoLists(l1, l2);}private ListNode mergeTwoLists(ListNode l1, ListNode l2) {if (l1 == null) return l2;if (l2 == null) return l1;if (l1.val < l2.val) {l1.next = mergeTwoLists(l1.next, l2);return l1;} else {l2.next = mergeTwoLists(l1,l2.next);return l2;}}
}

class Solution {
public:ListNode* mergeKLists(vector<ListNode*>& lists) {// if(lists.size()==0||lists[0].size()==0&&lists.size()==1) return NULL;priority_queue<int,vector<int>,greater<int>> q;int num=lists.size();ListNode* ans=new ListNode(0);ListNode* tmp=ans;for(int i=0;i<num;i++){while(lists[i]!=NULL){q.push(lists[i]->val);lists[i]=lists[i]->next;}} while(!q.empty()){int i=q.top();q.pop();ans->next=new ListNode(i);ans=ans->next;}return tmp->next;}
};

24. 两两交换链表中的节点

难度中等618

给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。

你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

示例:

给定 1->2->3->4, 你应该返回 2->1->4->3.

class Solution {
public:ListNode* swapPairs(ListNode* head) {if(head==NULL||head->next==NULL) return head;ListNode* h1=head;ListNode* h2=head->next;h1->next=swapPairs(h2->next);h2->next=h1;return h2;}
};

迭代写法:

class Solution {public ListNode swapPairs(ListNode head) {ListNode pre = new ListNode(0);pre.next = head;ListNode temp = pre;while(temp.next != null && temp.next.next != null) {ListNode start = temp.next;ListNode end = temp.next.next;temp.next = end;start.next = end.next;end.next = start;temp = start;}return pre.next;}
}作者:guanpengchn
链接:https://leetcode-cn.com/problems/swap-nodes-in-pairs/solution/hua-jie-suan-fa-24-liang-liang-jiao-huan-lian-biao/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

25. K 个一组翻转链表

难度困难720

给你一个链表,每 个节点一组进行翻转,请你返回翻转后的链表。

是一个正整数,它的值小于或等于链表的长度。

如果节点总数不是 的整数倍,那么请将最后剩余的节点保持原有顺序。

示例:

给你这个链表:1->2->3->4->5

当 = 2 时,应当返回: 2->1->4->3->5

当 = 3 时,应当返回: 3->2->1->4->5

说明:

  • 你的算法只能使用常数的额外空间。
  • 你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

这个要不再看看啊,反正我就会写递归.....

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode(int x) : val(x), next(NULL) {}* };*/
class Solution {
public:ListNode* reverseKGroup(ListNode* head, int k) {ListNode* tmp=head;int cnt=0;while(tmp!=NULL&&cnt<k){tmp=tmp->next;cnt++;}if(cnt<k) return head;ListNode* pre=NULL;ListNode* now=head;while(cnt--){tmp=now->next;now->next=pre;pre=now;now=tmp;}head->next=reverseKGroup(now,k);return pre;}
};

26. 删除排序数组中的重复项

难度简单1625

给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。

不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

示例 1:

给定数组 nums = [1,1,2], 函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。 你不需要考虑数组中超出新长度后面的元素。

示例 2:

给定 nums = [0,0,1,1,1,2,2,3,3,4],函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。你不需要考虑数组中超出新长度后面的元素。
class Solution {
public:int removeDuplicates(vector<int>& nums) {int index=1;if(nums.size()==0) return 0;if(nums.size()==1) return 1;for(int i=1;i<nums.size();i++){if(nums[i]!=nums[i-1]){nums[index]=nums[i];index++;}}return index;}
};

27. 移除元素

难度简单646

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

示例 1:

给定 nums = [3,2,2,3], val = 3,函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。

示例 2:

给定 nums = [0,1,2,2,3,0,4,2], val = 2,函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。
class Solution {
public:int removeElement(vector<int>& nums, int val) {int index=0;if(nums.size()==0) return 0;for(int i=0;i<nums.size();i++){if(nums[i]!=val){nums[index++]=nums[i];}}return index;}
};

28. 实现 strStr()

难度简单565

实现 strStr() 函数。

给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回  -1

示例 1:

输入: haystack = "hello", needle = "ll"
输出: 2

示例 2:

输入: haystack = "aaaaa", needle = "bba"
输出: -1

说明:

当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。

对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。

KMP算法,来学习

KMP 算法永不回退 txt 的指针 i,不走回头路(不会重复扫描 txt),而是借助 dp 数组中储存的信息把 pat 移到正确的位置继续匹配,时间复杂度只需 O(N),用空间换时间,所以我认为它是一种动态规划算法。

public class KMP {private int[][] dp;private String pat;public KMP(String pat) {this.pat = pat;// 通过 pat 构建 dp 数组// 需要 O(M) 时间}public int search(String txt) {// 借助 dp 数组去匹配 txt// 需要 O(N) 时间}
}作者:labuladong
链接:https://leetcode-cn.com/problems/implement-strstr/solution/kmp-suan-fa-xiang-jie-by-labuladong/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

为什么说 KMP 算法和状态机有关呢?是这样的,我们可以认为 pat 的匹配就是状态的转移。比如当 pat = "ABABC":

如上图,圆圈内的数字就是状态,状态 0 是起始状态,状态 5(pat.length)是终止状态。开始匹配时 pat 处于起始状态,一旦转移到终止状态,就说明在 txt 中找到了 pat。比如说当前处于状态 2,就说明AB匹配

另外,处于不同状态时,pat 状态转移的行为也不同。比如说假设现在匹配到了状态 4,如果遇到字符 A 就应该转移到状态 3,遇到字符 C 就应该转移到状态 5,如果遇到字符 B 就应该转移到状态 0:

KMP 算法最关键的步骤就是构造这个状态转移图。要确定状态转移的行为,得明确两个变量,一个是当前的匹配状态,另一个是遇到的字符;确定了这两个变量后,就可以知道这个情况下应该转移到哪个状态。

dp[j][c] = next
0 <= j < M,代表当前的状态
0 <= c < 256,代表遇到的字符(ASCII 码)
0 <= next <= M,代表下一个状态dp[4]['A'] = 3 表示:
当前是状态 4,如果遇到字符 A,
pat 应该转移到状态 3dp[1]['B'] = 2 表示:
当前是状态 1,如果遇到字符 B,
pat 应该转移到状态 2

算了好晕啊,换个人的看

因为已经匹配成功的字符串abc中没有相同的前后缀,所以下一次比对要从abcdabcy的首位开始比较。

让我们看看方块内的字符处于abc中的什么位置

在黄色框内,bc属于abc的后缀,ab属于abc的前缀,所以如果条件符合的话,abc需要有相同的前后缀

如果有相同的前后缀,我们就需要把前缀移动到后缀的位置上。

我们发现每当我们匹配失败,就需要寻找匹配成功的字符串中有没有相同的前后缀(最长的前后缀),然后再判定下一次比较要从哪一位开始。

代码再看看考研书。

LeetCode 21-30 题相关推荐

  1. 计算机四级网络工程师——操作系统部分题目笔记汇总【21~30题】

    计算机四级笔记 操作系统部分:(21~30题) 因篇幅过长,为保证学习质量,遂将其分成四部分(四篇博客) 每10题为一篇,其他题目在我的计算机四级考试网络工程师专栏可以找到 第21题: 文件系统实现文 ...

  2. LeetCode Week 3:第 21 ~ 30 题

    专栏--LeetCode 文章目录 专栏--LeetCode 21. 合并两个有序链表 22. 括号生成 23. 合并K个排序链表 24. 两两交换链表中的节点 25. K 个一组翻转链表 26. 删 ...

  3. Java基础50题(3) 21~30题

    2018.3.25 Java基础50题系列源码已上传到我的github仓库,有需要的可以自取,欢迎大家提出建议 https://github.com/Lawliet0717/Java-foudamen ...

  4. LeetCode 简单算法题

    使用Nodejs 抓取的LeetCode 简单算法题  一步一步来,先攻破所有简单的题目,有些题目不适合使用JS解决,请自行斟酌 Letcode 简单题汇总 104. Maximum Depth of ...

  5. LeetCode代码刷题(17~24)

    目录 17. 电话号码的字母组合 18. 四数之和 19. 删除链表的倒数第 N 个结点 20. 有效的括号 21. 合并两个有序链表 22. 括号生成 23. 合并K个升序链表 24. 两两交换链表 ...

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

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

  7. leetcode分类刷题笔记

    leetcode分类刷题笔记--基于python3 写在前面 1.做题如果实在想不出时间复杂度比较优的解法,可以先写出暴力解法,尝试在其基础上优化 2.排序.双指针.二分等--经常可以优化时间复杂度 ...

  8. leetcode贪心算法题集锦(持续更新中)

    leetcode贪心算法题集锦 leetcode贪心算法题集锦(持续更新中).python 和C++编写. 文章目录 leetcode贪心算法题集锦 一.贪心算法 1.盛最多水的容器 2.买股票的最佳 ...

  9. [剑指offer]面试题第[57]题[Leetcode][第167题][JAVA][和为s的两个数字][两数之和][HashSet][二分][双指针]

    [剑指offer]面试题第[57]题[Leetcode][第167题][第1题] 有序无序之分 题目输出不同之分 以下解法按照[剑指offer]面试题第[57]题进行题解 [问题描述][简单] 输入一 ...

  10. leetcode 21 java_LeetCode 21. 合并两个有序链表

    LeetCode 21. 合并两个有序链表 题目 将两个升序链表合并为一个新的升序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1->2->4, 1-> ...

最新文章

  1. c++概念模型的官方解释
  2. 搜索巨头争夺本地搜索市场
  3. vue打包配置发布路径
  4. OS / Linux / 系统阻塞在系统调用中时如果收到信号,系统如何处理?
  5. 缺少动态连接库.so--cannot open shared object file: No such file or directory
  6. SAP UI5 如何通过 manifest.json 文件定义第三方库依赖关系
  7. python3手机脚本教学_python+adb命令实现自动刷视频脚本案例
  8. AE 中的查找与定位,以城市查找为例
  9. 【kafka】利用 InfoSphere Data Replication CDC for Kafka 实现高效数据复制
  10. NeHe OpenGL第三十二课:拾取游戏
  11. 《逻辑与计算机设计基础(原书第5版)》——1.7 格雷码
  12. SpringSecurity下做POST测试以及传递实体
  13. android视频录制、另一部手机实时观看方案
  14. 测试质量报告-为了更好的下一个
  15. linux死机,Linux 死机了怎么办
  16. sql Server STUFF()函数
  17. 计算机网络基础——WWW万维网
  18. Ubuntu配置静态IP地址
  19. Winsows Server 2019 安装 PostgreSQL
  20. 采用TWH9248/9249的微波探测自动照明灯a

热门文章

  1. WSL2 中 docker volume 的位置
  2. 自己动手写一个网盘?
  3. 深度学习深度信念网络DBNs—简易详解
  4. OFGP 协议跨链解决方案
  5. 迭代训练集,随机抽取batch_size数量的图片,报错索引超出范围index out of range
  6. 朗润外盘国际期货:Cosmos 终局
  7. 揭阳市人民医院基于对称双数据中心的双活容灾系统建设项目
  8. 初探 MacBook Pro 刘海屏
  9. ppt演讲计时器_速来!提前面试PPT演讲干货!
  10. ni max不能连续采集图像_图像识别技术在智慧教室录播系统中的应用研究