【LeetCode】力扣刷题热题100道(11-15题)附源码 环形链表 二叉树中序遍历 插入法(C++)

devtools/2025/1/12 0:43:32/

目录

1.字母异位词分组

2.环形链表

3.环形链表2

4.二叉树的中序遍历

5.搜索插入位置


1.字母异位词分组

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。
字母异位词 是由重新排列源单词的所有字母得到的一个新单词。


排序字符:对于每个字符串,我们将其字符排序,得到一个唯一的 "排序后的字母" 作为该字符串的标识符(key)。
使用哈希表:利用哈希表(unordered_map)来将排序后的字母作为键(key),将相同字母异位词的字符串作为值(value)。如果两个字符串排序后得到相同的结果,它们属于同一组。
最终结果:哈希表中存储了多个键值对,其中每个键对应的值是一个字母异位词列表。

class Solution {
public:vector<vector<string>> groupAnagrams(vector<string>& strs) {unordered_map<string, vector<string>> anagrams;for (const string& str : strs) {string sorted_str = str;sort(sorted_str.begin(), sorted_str.end());anagrams[sorted_str].push_back(str);}vector<vector<string>> result;for (auto& pair : anagrams) {result.push_back(pair.second);}return result;}
};

unordered_map<string, vector<string>> anagrams;:使用哈希表 anagrams 来存储字母异位词。键是排序后的字符串,值是一个包含所有字母异位词的字符串数组。

遍历每个字符串:

对每个字符串 str,我们创建它的副本 sorted_str。
使用 sort() 函数对 sorted_str 进行排序。
将排序后的 sorted_str 作为哈希表的键,原字符串 str 被添加到相应的值(即字母异位词组)中。
提取结果:哈希表中的每个值都是一个字母异位词的组,我们将所有这些组收集到 result 数组中并返回。

2.环形链表

给你一个链表的头节点 head ,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。如果链表中存在环 ,则返回 true 。 否则,返回 false 。

初始化:

两个指针 slow 和 fast,都指向链表头部。
slow 每次走一步,fast 每次走两步。
循环遍历:

如果链表没有环,fast 指针最终会到达链表的末尾(即 fast 或 fast->next 为 NULL)。
如果链表有环,fast 指针和 slow 指针一定会相遇,因为 fast 走得比 slow 快,两者最终会在环内某个节点相遇。
判定条件:

如果在某个时刻 slow == fast,说明链表中存在环,返回 true。
如果 fast 指针走到链表末尾,即 fast 或 fast->next 为 NULL,说明链表没有环,返回 false。

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode(int x) : val(x), next(NULL) {}* };*/
class Solution {
public:bool hasCycle(ListNode *head) {if (!head || !head->next) return false; // 空链表或只有一个节点没有环ListNode *slow = head;  // 慢指针ListNode *fast = head;  // 快指针while (fast && fast->next) {slow = slow->next;        // 慢指针走一步fast = fast->next->next;  // 快指针走两步if (slow == fast) {return true;  // 快慢指针相遇,说明链表中有环}}return false;  // 快指针走到链表末尾,说明无环}
};

3.环形链表2

给定一个链表的头节点  head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。不允许修改 链表

初始化:

设置两个指针 slow 和 fast,都指向链表的头部。
环的检测:

slow 每次移动一步,fast 每次移动两步。
如果链表存在环,slow 和 fast 会在环中相遇。
如果链表没有环,fast 会在没有环的链表中走到 NULL,循环结束。
寻找环的入口:

当 slow 和 fast 相遇时,说明链表中有环。
将 slow 指针保持在相遇点,并将 entry 指针指向链表的头部。
然后,两个指针都以相同的速度(每次一步)移动,直到它们相遇。相遇点就是环的入口节点。
返回值:如果链表有环,返回环的入口节点;如果链表没有环,返回 NULL。

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode(int x) : val(x), next(NULL) {}* };*/
class Solution {
public:ListNode *detectCycle(ListNode *head) {if (!head || !head->next) return NULL;  // 空链表或者只有一个节点没有环ListNode *slow = head;  // 慢指针ListNode *fast = head;  // 快指针// 检测链表是否有环while (fast && fast->next) {slow = slow->next;        // 慢指针走一步fast = fast->next->next;  // 快指针走两步if (slow == fast) {// 当快慢指针相遇,说明有环ListNode *entry = head;  // 入口指针从头开始while (entry != slow) {entry = entry->next;slow = slow->next;}return entry;  // 返回环的入口节点}}return NULL;  // 没有环}
};

4.二叉树的中序遍历

给定一个二叉树的根节点root ,返回 它的 中序 遍历 。

如下为代码:

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:vector<int> inorderTraversal(TreeNode* root) {vector<int> result;stack<TreeNode*> stk;TreeNode* curr = root;while (curr != nullptr || !stk.empty()) {while (curr != nullptr) {stk.push(curr);curr = curr->left;}curr = stk.top();stk.pop();result.push_back(curr->val);curr = curr->right;}return result;}
};

vector<int> result; 用来存储中序遍历的结果。
stack<TreeNode*> stk; 用来模拟递归过程中访问的栈。
TreeNode* curr = root; 将 curr 初始化为二叉树的根节点,用来遍历树。
while (curr != nullptr || !stk.empty()):这个循环会一直进行,直到遍历完所有节点。条件判断包括两部分:
curr != nullptr:表示当前节点还存在。
!stk.empty():表示栈不为空,说明还有节点待访问。
while (curr != nullptr):这个内层循环将沿着左子树访问,直到当前节点为空。
在每一步,当前节点 curr 会被压入栈中 (stk.push(curr);),然后将 curr 移动到左子节点 (curr = curr->left;)。
当左子树遍历完毕后,栈顶的节点就是当前最左的节点。
curr = stk.top(); 从栈中取出栈顶节点,即当前最左的节点。
stk.pop(); 弹出栈顶节点,因为这个节点已经被访问过。
result.push_back(curr->val); 将当前节点的值添加到结果数组中。
curr = curr->right; 将 curr 移动到右子树节点,继续进行下一个循环。

5.搜索插入位置

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

请必须使用时间复杂度为 O(log n) 的算法

代码如下所示:

class Solution {
public:int searchInsert(vector<int>& nums, int target) {int left = 0;int right = nums.size() - 1;while (left <= right) {int mid = left + (right - left) / 2; if (nums[mid] == target) {return mid; } else if (nums[mid] < target) {left = mid + 1;  } else {right = mid - 1; }}return left;}
};

int left = 0; 和 int right = nums.size() - 1;:初始化左右指针,分别指向数组的头部和尾部。
while (left <= right):这个循环会持续进行,直到找到目标值或确定目标值的插入位置。
int mid = left + (right - left) / 2;:计算中间位置。使用 left + (right - left) / 2 来避免 left + right 可能出现的溢出问题。
if (nums[mid] == target):如果 mid 位置的元素等于目标值,直接返回该索引。
else if (nums[mid] < target):如果 mid 位置的元素小于目标值,目标值应该在 mid 右侧,更新 left = mid + 1。
else:如果 mid 位置的元素大于目标值,目标值应该在 mid 左侧,更新 right = mid - 1。
return left;:如果循环结束时没有找到目标值,left 将指向目标值应该插入的位置。


http://www.ppmy.cn/devtools/149735.html

相关文章

Ubuntu 24.04 LTS系统安装Docker踩的坑

一开始我跟着Docker给出的官网文档 Ubuntu | Docker Docs 流程走&#xff0c;倒腾了两个多小时&#xff0c;遇到了各种坑&#xff0c;最后放弃了。在我们使用脚本安装Docker命令前&#xff0c;我们先把已经安装的Docker全部卸载掉。 卸载Docker 1.删除docker及安装时自动安装…

Springboot3.x工程创建及必要引用(基础篇)

下面从环境的安装和配置开始&#xff0c;到Springboot3.x工程创建&#xff0c;记录一下让完全没有基础的小白用户也能够开始自己的第一个项目。 准备 安装JDK环境&#xff08;这里最好安装JDK17及以上版本&#xff09;安装IntelliJ IDEA Ultimate工具&#xff08;可以从官网下…

第37周:咖啡豆识别 (Tensorflow实战第七周)

目录 前言 一、前期工作 1.1 设置GPU 1.2 导入数据 输出 二、数据预处理 2.1 加载数据 2.2 可视化数据 2.3 配置数据集 三、构建VGG-16网络 3.1 VGG-16网络介绍 3.2 搭建VGG-16模型 3.2.1 直接调用官方 3.2.2 自建模型 四、编译 4.1 设置动态学习率 五、模型训…

基于Qt的OFD阅读器开发原理与实践

摘要 本文详细探讨了基于Qt开发OFD阅读器的原理与实践。通过解析OFD文件格式、构建文档结构、实现页面渲染、处理用户交互以及进行性能优化&#xff0c;本文展示了如何使用Qt框架开发一个功能强大、性能优异的OFD阅读器。文章还提供了示例代码和未来发展方向&#xff0c;为开发…

Qt天气预报系统鼠标拖动窗口

Qt天气预报系统 1、鼠标拖动窗口1.1重写鼠标移动函数1.2添加定义1.3定义一个偏移值1.4判断鼠标左键是否被按下1.5计算当前鼠标位置与窗口左上角位置的偏移值1.6移动窗口 2、.h文件和.cpp文件2.1 .h文件2.2 .cpp文件 3、结论 1、鼠标拖动窗口 1.1重写鼠标移动函数 protected:v…

新冠肺炎服务预约微信小程序的设计与实现ssm+论文源码调试讲解

第4章 系统设计 4.1 系统设计的原则 在系统设计过程中&#xff0c;也需要遵循相应的设计原则&#xff0c;这些设计原则可以帮助设计者在短时间内设计出符合设计规范的设计方案。设计原则主要有可靠性&#xff0c;安全性&#xff0c;可定制化&#xff0c;可扩展性&#xff0c;可…

springCloudGateWay使用总结

1、什么是网关 功能: ①身份认证、权限验证 ②服务器路由、负载均衡 ③请求限流 2、gateway搭建 2.1、创建一个空项目 2.2、引入依赖 2.3、加配置 3、断言工厂 4、过滤工厂 5、全局过滤器 6、跨域问题

智慧公厕大数据驱动下的公共卫生管理与优化

在快速发展的城市化进程中&#xff0c;公共卫生问题日益凸显&#xff0c;成为城市管理的重要议题。智慧公厕&#xff0c;作为公共卫生设施的一次革命性创新&#xff0c;正借助物联网技术的东风&#xff0c;引领公共卫生进入一个全新的生态时代。本文将深入探讨智慧公厕如何利用…