242.有效的字母异位词,349. 两个数组的交集,202题. 快乐数,1. 两数之和

简介: 以下是根据您提供的内容编写的一段简介:在算法学习中,掌握高效解法和数据结构至关重要。本文通过解析四道LeetCode经典题目(242.有效的字母异位词、349.两个数组的交集、202.快乐数、1.两数之和),深入探讨了多种优化思路与常用数据结构的应用。例如,使用数组统计字符频率判断异位词,利用`unordered_set`实现集合交集去重,借助`unordered_map`优化两数之和的查找效率,以及通过哈希表检测快乐数循环问题。这些方法不仅提升了时间复杂度,还强化了对`map`、`set`等数据结构的理解,为解决类似问题提供了重要参考。

题目:242.有效的字母异位词

Leetcode原题:242. 有效的字母异位词

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。

注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。

示例 1:

输入: s = "anagram", t = "nagaram"

输出: true

示例 2:

输入: s = "rat", t = "car"

输出: false

提示:

1 <= s.length, t.length <= 5 * 104

s 和 t 仅包含小写字母

思考历程与知识点:  

如果一个字母一个字母的找,也就是暴力,用两个for的话时间复杂度是O(N^2);

我们可以换个思路,a~z一共26个字母,我们开一个长度26的数组 f,把每个字母出现的次数记录下来, a 就是 f [0], b 就是 f [1],c就是 f [2] , 依此类推,第二个字符串也是同样开一个26的数组 f2 [ ]。最后只需要对比两个数组里的次数是否都相同就可以了。

题解:

class Solution {
public:
    bool isAnagram(string s, string t) {
        int f[26]={0},f2[26]={0};
 
        if(s.size()!=t.size())return false;// 长度不一样的话,肯定不对
       
        for(int i = 0; i < s.size(); i++) {
            f[s[i] - 'a']++;
            f2[t[i] - 'a']++;
        }
 
        for(int i = 0; i < 26; i++) {
            if(f[i] != f2[i]) return false;
        }
 
        return true;
 
    }
};

题目:349. 两个数组的交集

Leetcode原题:349. 两个数组的交集

给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。

示例 1:

输入:nums1 = [1,2,2,1], nums2 = [2,2]

输出:[2]

示例 2:

输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]

输出:[9,4]

解释:[4,9] 也是可通过的

提示:

1 <= nums1.length, nums2.length <= 1000

0 <= nums1[i], nums2[i] <= 1000

思考历程与知识点:  

题目很简单,求集合,用数组可以做,但我们尝试学习set的方法来完成。

介绍今天要学习的新东西:unordered_set.

unordered_set: 无序set, set里的值不能重复。

unordered_set用在这个去重的题目里就特别合适了,,可以直接把重复值去掉。

具体如何使用看下面题解应该就明白了。

题解:

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> res; // 存放结果,之所以用set是为了给结果集去重
        unordered_set<int> nums_set(nums1.begin(), nums1.end());//把nums1再存为 unordered_set.因为vector没有find函数。
        for (int i=0;i<nums2.size();i++) {
            // 发现nums2的元素 在nums_set里又出现过
            if (nums_set.find(nums2[i]) != nums_set.end()) {
                res.insert(nums2[i]);在res结果数组中插入数字
            }
        }
        return vector<int>(res.begin(), res.end());
    }
};

题目:202题. 快乐数

Leetcode原题:202. 快乐数

编写一个算法来判断一个数 n 是不是快乐数。

「快乐数」 定义为:

对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。

然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。

如果这个过程 结果为 1,那么这个数就是快乐数。

如果 n 是 快乐数 就返回 true ;不是,则返回 false 。

示例 1:

输入:n = 19

输出:true

解释:

12 + 92 = 82

82 + 22 = 68

62 + 82 = 100

12 + 02 + 02 = 1

示例 2:

输入:n = 2

输出:false

提示:

1 <= n <= 231 - 1

思考历程与知识点:  

题目特意说明,可能会无限循环,也就是sum和可能相等,所以需要记录sum,当重复的时候进行退出。

题解:

class Solution {
public:
    // 取数值各个位上的单数之和
    int getSum(int n) {
        int sum = 0;
        while (n) {
            sum += (n % 10) * (n % 10);
            n /= 10;
        }
        return sum;
    }
    bool isHappy(int n) {
        unordered_set<int> set;
        while(1) {
            int sum = getSum(n);
            if (sum == 1) {
                return true;
            }
            // 如果这个sum曾经出现过,说明已经陷入了无限循环了,立刻return false
            if (set.find(sum) != set.end()) {
                return false;
            } else {
                set.insert(sum);
            }
            n = sum;
        }
    }
};

题目:1. 两数之和

Leetcode原题链接:1. 两数之和(Leetcode的第一道题)

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

示例 1:

输入:nums = [2,7,11,15], target = 9

输出:[0,1]

解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

示例 2:

输入:nums = [3,2,4], target = 6

输出:[1,2]

示例 3:

输入:nums = [3,3], target = 6

输出:[0,1]

提示:

2 <= nums.length <= 104

-109 <= nums[i] <= 109

-109 <= target <= 109

只会存在一个有效答案

思考历程与知识点:  

如果暴力来做,两个for,时间复杂度O(N^2),这里我们还是尝试学习进行优化。

新知识点:map。

map: 可以看做是一个动态数组,类似于vector<int> a, 但是map[n] 会根据n的大小进行自动排序。n可以为int, 也可以是string等其他类型,这是数组做不到的。后续做到字符串的题时我们会用到这个特性。

创建一个空map, 并遍历一遍数组。每次都在map中找,是否有相应的数字,如果没有就把数字和对应下标加进map里,进行下一个数字的查找。

为什么不干脆先把所有的数字和下标全存进map再进行查找,而是先建立空map再一个一个的把不符话的数字存进map呢?

因为题目说了,不能包括自己。如果全部先存进map,那么遇到5+5=10这种情况,即使只有1个5,它仍然遍历成功,因为确实找到了5呀,所以为了避免这种情况,每次都先查找再加入当前数字,保证当前这个数字不会被查找到。

题解:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map <int,int> map;
        for(int i = 0; i < nums.size(); i++) {
            // 遍历当前元素,并在map中寻找是否有匹配的key
            auto iter = map.find(target - nums[i]);  
            if(iter != map.end()) {
                return {iter->second, i};
            }
            // 如果没找到匹配对,就把访问过的元素和下标加入到map中
            map.insert(pair<int, int>(nums[i], i));  
        }
        return {};
    }
};


相关文章
|
机器学习/深度学习 数据采集 算法
利用深度学习优化图像识别准确性的策略与挑战
在计算机视觉领域,图像识别的准确性直接关系到技术的实用性和可靠性。本文旨在探讨通过深度学习技术提升图像识别系统性能的有效策略,并分析当前面临的主要技术和实践挑战。文中首先回顾了深度学习在图像识别中的应用进展,然后详细介绍了数据预处理、网络结构优化、迁移学习等关键技术点。最后,文章讨论了数据集偏差、计算资源限制以及模型泛化能力等挑战,并提出可能的解决方案。本研究为图像识别技术的发展提供参考,同时对实现更高效、准确的图像处理系统具有重要指导意义。
|
6月前
|
算法
491.递增子序列, 46.全排列, 47.全排列 II
**简介:** 本文介绍了三道经典的回溯算法题目及其解法,分别是“491. 递增子序列”、“46. 全排列”和“47. 全排列 II”。其中,“491”要求从数组中找出所有不同的递增子序列,需注意去重且不能对原数组排序;“46”是求不含重复数字数组的所有全排列,使用布尔数组记录元素使用状态;“47”则针对含重复数字的数组求不重复的全排列,通过排序与树层去重实现。 这些题目涵盖了回溯算法中的常见问题类型,如子集、排列以及去重处理,帮助读者深入理解回溯算法的核心思想与实现细节。代码示例详细展示了如何通过递归与剪枝优化解决问题,是学习回溯算法的经典案例。
|
6月前
|
自然语言处理 API 开发工具
端午出游高定:通义灵码+高德 MCP 10 分钟定制出游攻略
本文介绍了如何使用通义灵码编程智能体和高德MCP 2.0制作北京端午3天旅行攻略页面。首先需下载通义灵码AI IDE并获取高德申请的key,通过添加MCP服务、生成travel_tips.html文件完成初步攻略制作。用户可自定义页面风格、固定基础功能页面生成,并扩展MCP服务以满足多样化需求。文章还详细描述了开发专属MCP服务的过程,包括借助通义灵码编写代码、部署服务及调用工具,最终实现个性化旅游攻略生成。此外,提供了相关资料和参考链接,方便读者深入了解和实践。
|
6月前
|
存储 芯片
移动硬盘突然打不开了?别急,有办法解决
对于不少人来说,移动硬盘是存放重要文件、照片、视频和备份资料的“宝库”。但在某天,当你满怀期待地将移动硬盘插入电脑时,却发现它根本打不开,甚至连盘符都不见了。这时候,不少人第一反应就是“完了,数据是不是没了?”别急,移动硬盘打不开不等于数据彻底消失。本文将带你逐步排查问题,并分享一些切实可行的解决方法。
|
6月前
|
JavaScript 前端开发 UED
【HarmonyOS Next之旅】基于ArkTS开发(二) -> UI开发四
本文介绍了Web组件开发与性能优化的相关内容。在Web组件开发部分,涵盖创建组件、设置样式与属性、添加事件和方法以及场景示例,如动态播放视频。性能提升方面,推荐使用数据懒加载、条件渲染替代显隐控制、Column/Row替代Flex、设置List组件宽高及调整cachedCount减少滑动白块等方法,以优化应用性能与用户体验。
267 56
|
9月前
|
边缘计算 安全 数据安全/隐私保护
一个pcdn产品体验
闲置宽带还能赚钱?听起来是不是很神奇?作为一名普通打工人,我最近入手了负三云这个“小盒子”,体验后直呼真香!只需将其连接路由器,就能利用闲置带宽获取收益。我家100M宽带,每天稳定收入5-8元,一个月轻松赚200+,完全覆盖网费。安装简单、不影响网速,功耗低且安全可靠。如果你也想尝试边缘计算,低成本的负三云绝对值得一试!
2857 0
|
6月前
|
存储 机器学习/深度学习 缓存
软考软件评测师——计算机组成与体系结构(分级存储架构)
本内容全面解析了计算机存储系统的四大核心领域:虚拟存储技术、局部性原理、分级存储体系架构及存储器类型。虚拟存储通过软硬件协同扩展内存,支持动态加载与地址转换;局部性原理揭示程序运行特性,指导缓存设计优化;分级存储架构从寄存器到外存逐级扩展,平衡速度、容量与成本;存储器类型按寻址和访问方式分类,并介绍新型存储技术。最后探讨了存储系统未来优化趋势,如异构集成、智能预取和近存储计算等,为突破性能瓶颈提供了新方向。
|
6月前
|
算法
104.二叉树的最大深度 , 111.二叉树的最小深度,222.完全二叉树的节点个数
本内容主要讲解了三道与二叉树相关的算法题及其解法,包括“二叉树的最大深度”、“二叉树的最小深度”和“完全二叉树的节点个数”。通过递归方法(前序或后序遍历)实现求解。 - **最大深度**:利用后序遍历计算根节点到最远叶子节点的路径长度。 - **最小深度**:同样采用后序遍历,但需特别处理单子树为空的情况,确保找到从根到最近叶子节点的路径。 - **完全二叉树节点数**:基于递归后序遍历统计左右子树节点数量并累加。 代码示例清晰展示了递归逻辑,帮助理解二叉树深度与高度的概念及其实现方式。
|
9月前
|
JavaScript 前端开发 数据可视化
20.6K star!Excel级交互体验!这款开源Web表格神器绝了!
Handsontable 是一款功能强大的 JavaScript 数据表格组件,提供类 Excel 的交互体验。支持实时协作、数据绑定、公式计算等企业级功能,可轻松集成到 React/Vue/Angular 等主流框架。
1668 11