当前位置: 首页 > news >正文

Leetcode刷题

目录

一、链表中的环问题

141. 环形链表:判断链表是否有环 

142. 环形链表 II:找到入环的第一个节点

二、字符串处理问题

942. 增减字符串匹配

409. 最长回文串

三、数组贪心问题:870. 优势洗牌 

总结


在算法学习的路上,刷题是提升能力的关键途径。今天我们来剖析几道经典的算法题目,涵盖链表、字符串、数组等多个领域,一起看看它们的解题思路和代码实现。
 

一、链表中的环问题

141. 环形链表:判断链表是否有环 

这道题可以用快慢指针法(龟兔赛跑算法)来解决。我们定义两个指针,慢指针一次走一步,快指针一次走两步。如果链表中存在环,那么快慢指针最终一定会相遇;如果快指针走到了链表末尾( null ),则说明链表无环。

class Solution {
public:bool hasCycle(ListNode* head) {ListNode *slow, *fast;slow = fast = head;while (fast && fast->next) {slow = slow->next;fast = fast->next->next;if (slow == fast)return true;}return false;}
};

142. 环形链表 II:找到入环的第一个节点


这道题是上一题的进阶。当快慢指针相遇后,我们再定义一个指针从链表头出发,慢指针继续从相遇点出发,两者每次都走一步,最终相遇的节点就是入环的第一个节点。
 
原理是:设链表头到入环点的距离为 a ,环的长度为 b 。快慢指针相遇时,慢指针走了 a + x ,快指针走了 a + x + nb ( n 是快指针绕环的圈数)。又因为快指针速度是慢指针的两倍,所以 2(a + x) = a + x + nb ,化简得 a = nb - x 。这意味着从头节点和相遇点同时出发的指针,会在入环点相遇。

class Solution {
public:ListNode* detectCycle(ListNode* head) {ListNode *fast, *slow;slow = fast = head;while (fast && fast->next) {fast = fast->next->next;slow = slow->next;if (fast == slow) {ListNode* index1 = fast;ListNode* index2 = head;while (index1 != index2) {index1 = index1->next;index2 = index2->next;}return index1;}}return nullptr;}
};

二、字符串处理问题

942. 增减字符串匹配


这道题可以用双指针贪心的思路解决。我们定义 left 指针指向当前可用的最小数, right 指针指向当前可用的最大数。遍历字符串 s :
 
- 若当前字符是 'I' ,说明下一个数要比当前大,所以选当前最小的数 left ,并将 left 右移;
- 若当前字符是 'D' ,说明下一个数要比当前小,所以选当前最大的数 right ,并将 right 左移;
- 最后把剩下的那个数加入结果即可。

class Solution {
public:vector<int> diStringMatch(string s) {int n = s.size();int left = 0, right = n;vector<int> ret;for (auto e : s) {if (e == 'I') ret.push_back(left++);else ret.push_back(right--);}ret.push_back(left++);return ret;}
};

409. 最长回文串


回文串的特点是对称,所以我们可以统计每个字符出现的次数。对于出现偶数次的字符,可以全部用来构造回文串;对于出现奇数次的字符,我们可以用其偶数部分,并且最多可以保留一个奇数次数的字符作为回文串的中心。
 

class Solution {
public:int longestPalindrome(string s) {vector<int> str(129); // 涵盖大小写字母的ASCII范围for (auto e : s) str[e]++;int ret = 0, flag = 0;for (auto e : str) {if (e % 2 == 0) ret += e;else {flag = 1;ret += e - 1;}}return flag ? ret + 1 : ret;}
};

三、数组贪心问题:870. 优势洗牌 


这道题的核心是最大化优势,即让 nums1 中尽可能多的元素大于 nums2 中对应位置的元素。我们可以用排序和双指针的方法:
 
- 先对 nums1 排序,再对 nums2 按元素大小排序(同时记录原始索引);
- 用双指针分别指向 nums1 的头和 nums2 的头/尾:如果 nums1 的当前最小值大于 nums2 的当前最小值,就将这两个元素匹配;否则,将 nums1 的当前最小值与 nums2 的当前最大值匹配,这样可以尽可能保留 nums1 中较大的元素去匹配 nums2 中较小的元素。

class Solution {
public:vector<int> advantageCount(vector<int>& nums1, vector<int>& nums2) {int n = nums2.size();vector<int> index(n);vector<int> ret(n);for (int i = 0; i < n; i++) index[i] = i;sort(nums1.begin(), nums1.end());// 对nums2的索引按nums2元素大小排序sort(index.begin(), index.end(), [&](int i, int j) { return nums2[i] < nums2[j]; });int left = 0, right = n - 1;for (int i = 0; i < n; i++) {if (nums1[i] > nums2[index[left]]) {ret[index[left++]] = nums1[i];} else {ret[index[right--]] = nums1[i];}}return ret;}
};

总结


以上几道题涵盖了快慢指针、贪心、哈希统计等多种算法思想。在刷题时,我们要注重理解题目的本质,提炼解题模型,这样才能在遇到类似问题时举一反三。希望这篇笔记能对大家的算法学习有所帮助,一起加油刷题吧!

http://www.dtcms.com/a/447546.html

相关文章:

  • 免费个人网站域名青岛网站建设要多少钱
  • 看ppo 训练900步 打开笔记本写点东西保存 归一化 explained_variance | 0.161
  • 网站做广告投放 做销售线索预估网页设计心得体会800字
  • Hi3516DV500/HI3519DV500开发笔记之烧写固件
  • WordPress博客整站带数据如何介绍自己的设计方案
  • h5网站开发定制长沙教育网站建设
  • 装修公司网站该怎么做网站运营配置
  • 网站建设综合工业设计完整作品集
  • 9. Pandas 数据统计与汇总分析
  • 住房和城乡建设部网站行标wordpress 登
  • 南宁建站方案化工网站模板免费下载
  • Sora 2为什么会火?
  • 专门做正品的网站有哪些wordpress与cms哪个好用
  • 舟山市城市建设档案馆网站广东网站建设哪里有
  • 织梦教育网站开发西安淘宝网站建设公司哪家好
  • 公司网站制作流程2016保定小程序开发公司
  • JAVA——线程池
  • 做网站方面wordpress使用端口
  • 邵阳县做网站企业门户网站建设论文
  • 武冈网站建设鹤山市网站建设公司
  • 网站集约化建设方案2345网址导航官网下载大全
  • 企业建设网站的资金策划做赌场网站犯法么
  • 时延抖动的物理本质
  • 外包程序员的出路优化算法 网站
  • 绵阳做网站的WordPress投票主题系统
  • 网站开发实训周报wordpress wdlog主题
  • 没有注册公司可以做网站吗seo做的好的网站 知乎
  • 【C++实战(73)】解锁C++游戏开发新姿势:SFML实战入门
  • 汕头网站定制南京市住房和城乡建设厅网站
  • app ui设计欣赏 网站牡丹江哈尔滨网站建设