基础知识

哈希 常见的结构(不要忘记数组)

  • 数组
  • set (集合)
  • map(映射)

注意 哈希冲突 哈希函数

LeetCode 242

分析1.0

HashMap<Character, Integer> 记录字符元素及其个数,再以字符序列对key进行排序,比较两个Map是否一致或者是遍历Map1的时候,在map2中对cur指针key查询对应个数

有一个用例未通过

原因:

引用类型比较值使用equals().方法map1.get(c).equals(map2.get(c)) 
class Solution {
public boolean isAnagram(String s, String t) {
int sizeS = 0, sizeT = 0;
HashMap<Character,Integer> map1 = new HashMap();
HashMap<Character,Integer> map2 = new HashMap();
for(int i = 0; i < s.length(); i++){
map1.put(s.charAt(i), map1.getOrDefault(s.charAt(i),0)+1);
}
for(int j = 0; j < t.length(); j++){
map2.put(t.charAt(j), map2.getOrDefault(t.charAt(j),0)+1);
}
System.out.println(map1);
System.out.println(map2);
// 光size相同不行 要size同而且对应的元素也同
sizeS = map1.size();
sizeT = map2.size();
if(sizeS != sizeT){
return false;
}
for(Character c : map1.keySet()){
if(map2.get(c) == null){
return false;
}
if(map1.get(c) != map2.get(c)){
return false;
}
}
return true;
}
}

分析2.0

数组也是一个hash表,它的key就是索引,元素就是value 要将普通的key一一对应为数组的index

LeetCode 349

分析1.0

两个数组,找他们的公共集合,集合元素不重复

思路:遍历较短数组,如果长数组中存在这个元素,加入Set,最后将Set转换成int[]

在第二个for循环中,可用contains()方法判断元素是否在集合中

class Solution {
public int[] intersection(int[] nums1, int[] nums2) {
HashSet<Integer> set = new HashSet();
for(int i = 0; i < nums1.length; i++){
for(int j = 0; j < nums2.length; j++){
if(nums1[i] == nums2[j]){
set.add(nums1[i]);
}
}
}
int[] ans = new int[set.size()];
int index = 0;
for(Integer temp : set){
ans[index++] = temp.intValue();
}
return ans;
}
}

LeetCode 202

分析1.0

元素是正整数,分离各个位置上的元素,求和判断是否为快乐数

如何判断循环终止条件-出现无限循环数,将所有数存进set,当存在相同数时即进入循环

class Solution {
public boolean isHappy(int n) {
HashSet<Integer> set = new HashSet();
set.add(n);
while(true){
int val = getVal(n);
System.out.println(val);
if(val == 1){
//System.out.println(set);
return true;
}
if(set.contains(val)){
//System.out.println(set);
return false;
}else{
set.add(val);
n = val;
}
}
}
public int getVal(int n){
int ans = 0;
while(n != 0){
ans += (n%10)*(n%10);
n = n / 10;
}
return ans;
}
}

分析2.0

说白了就是找到循环退出的条件,循环继续下去的条件

LeetCode 1

分析1.0 

将数组元素去重存放进HashMap<Integer,Integer> (元素值,索引)达到去重功能,接着两层for循环解决问题,将结果添加进int[] ans返回

class Solution {
public int[] twoSum(int[] nums, int target) {
HashMap<Integer, Integer> map = new HashMap();
int[] ans = new int[2];
for(int i = 0; i < nums.length; i++){
map.put(nums[i], i);
}
for(Integer val1 : map.keySet()){
int cnt = 0;
for(Integer val2 : map.keySet()){
if(cnt == 0){
cnt++;
continue;
}
if(val1 + val2 == target){
ans[0] = map.get(val1).intValue();
ans[1] = map.get(val2).intValue();
return ans;
}
}
}
return ans;
}
}

问题

  1. [3,3] 6这样的用例就不行了
  2. 这样遍历每次val1 val2初值是一样的
  3. 其实哈希表的作用就在于去重+判断是否存在某个元素 怎么利用特性去写代码还是很要紧的
for(Integer val1 : map.keySet()){
for(Integer val2 : map.keySet()){
if(val1 + val2 == target){
ans[0] = map.get(val1).intValue();
ans[1] = map.get(val2).intValue();
return ans;
}
}
}

已经遍历的部分+当前遍历元素+未遍历部分

for(int i = 0; i < nums.length; i++){
int temp = target - nums[i]; // 遍历当前元素,并在map中寻找是否有匹配的key
if(map.containsKey(temp)){
res[1] = i;
res[0] = map.get(temp);
break;
}
map.put(nums[i], i); // 如果没找到匹配对,就把访问过的元素和下标加入到map中
}

分析2.0 

这题具体情况具体分析不就是一个暴力for循环能解决的事儿吗???

class Solution {
public int[] twoSum(int[] nums, int target) {
int[] ans = new int[2];
for(int i = 0; i< nums.length-1; i++){
for(int j = i+1; j < nums.length; j++){
if(nums[i] + nums[j] == target){
ans[0] = i;
ans[1] = j;
return ans;
}
}
}
return ans;
}
}

分析3.0

其实就是找两个数,遍历的当前元素算一个,那剩下的肯定就只能在已经遍历或者未遍历的元素中找,暴力for循环就是在未遍历的元素中找,Map的contains就是在已经遍历过的元素中找,但是有一个很巧妙的思维就是

int temp = target - nums[i]

不用像普通暴力双层for循环那样猛烈

总结

  1. 引用类型比较值使用equals()
  2. HashMap默认是按照key字典序进行存储的 可打印验证
  3. key - 数组下标 - value
  4. 字符转数字 '字符' - 'a' 得到的就是对应26个字符的序数
  5. 明确题目要求,有时它只需要一个结果,如何操作数据、要不要操作数据是一个问题
  6. Integer泛型得到的集合不能直接转成int[] 
  7. int[] arr 必须初始化后才能进行操作 不能直接int[] arr = 另外一个数组
  8. Set HashMap 遍历过程 这个没法儿用xx.get(index)访问元素
  9. 找到循环退出的条件,循环继续下去的条件
  10. 查询一个元素是否出现过,或者一个元素是否在集合里的时候,就要第一时间想到哈希法
  11. 判断特殊情况-定义返回结果-找准循环开始/结束边界条件-打日志定位错误
  12. 数组特殊情况
    if(nums == null || nums.length == 0){
    return res;
    }
  13. 抽象思维 已经遍历的部分+当前遍历元素+未遍历部分 遍历过的部分存进map用contains()判断 判断的时候要知道你还缺哪个元素

常用变量名增量更新

size、val、ans、cnt、cur、pre、next、left、right、index、gap、target、res

代码随想录算法训练营day06 | leetcode 242、349 、202、1的更多相关文章

  1. 【算法训练营day4】LeetCode24. 两两交换链表中的结点 LeetCode19. 删除链表的倒数第N个结点 LeetCode面试题 02.07. 链表相交 LeetCode142. 环形链表II

    [算法训练营day4]LeetCode24. 两两交换链表中的结点 LeetCode19. 删除链表的倒数第N个结点 LeetCode面试题 02.07. 链表相交 LeetCode142. 环形链表 ...

  2. 前端与算法 leetcode 242. 有效的字母异位词

    目录 # 前端与算法 leetcode 242. 有效的字母异位词 题目描述 概要 提示 解析 解法一:哈希表 解法二:数组判断字符出现次数 解法三:转换字符串 算法 传入测试用例的运行结果 执行结果 ...

  3. 【算法训练营day7】LeetCode454. 四数相加II LeetCode383. 赎金信 LeetCode15. 三数之和 LeetCode18. 四数之和

    [算法训练营day7]LeetCode454. 四数相加II LeetCode383. 赎金信 LeetCode15. 三数之和 LeetCode18. 四数之和 LeetCode454. 四数相加I ...

  4. 【算法训练营day1】LeetCode704. 二分查找 LeetCode27. 移除元素

    [算法训练营day1]LeetCode704. 二分查找 LeetCode27. 移除元素 LeetCode704. 二分查找 题目链接:704. 二分查找 初次尝试 看到题目标题是二分查找,所以尝试 ...

  5. 【算法训练营day8】LeetCode344. 反转字符串 LeetCode541. 反转字符串II 剑指Offer05. 替换空格 LeetCode151. 翻转字符串里的单词 剑指Offer58-II. 左旋转字符串

    [算法训练营day8]LeetCode344. 反转字符串 LeetCode541. 反转字符串II 剑指Offer05. 替换空格 LeetCode151. 翻转字符串里的单词 剑指Offer58- ...

  6. C#版[击败99.69%的提交] - Leetcode 242. 有效的同构异形词 - 题解

    C#版 - Leetcode 242. 有效的同构异形词 - 题解 Leetcode 242.Valid Anagram 在线提交: https://leetcode.com/problems/val ...

  7. 【算法题 14 LeetCode 147 链表的插入排序】

    算法题 14 LeetCode 147 链表的插入排序: 解题代码: # Definition for singly-linked list. # class ListNode(object): # ...

  8. 代码随想录第十三天 | 150. 逆波兰表达式求值、239. 滑动窗口最大值、347.前 K 个高频元素

    第一题150. 逆波兰表达式求值 根据 逆波兰表示法,求表达式的值. 有效的算符包括 +.-.*./ .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 注意 两个整数之间的除法只保留整数部分. ...

  9. 代码随想录第八天 |344.反转字符串 、541. 反转字符串II、剑指Offer 05.替换空格 、151.翻转字符串里的单词 、剑指Offer58-II.左旋转字符串

    第一题344.反转字符串 编写一个函数,其作用是将输入的字符串反转过来.输入字符串以字符数组 s 的形式给出. 不要给另外的数组分配额外的空间,你必须原地修改输入数组.使用 O(1) 的额外空间解决这 ...

  10. LeetCode初级算法之字符串:242 有效的字母异位词

    有效的字母异位词 题目地址:https://leetcode-cn.com/problems/valid-anagram/ 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位 ...

随机推荐

  1. jquery 操作样式

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. python模块/导入模块

    索引取值与迭代取值的差异 l1 = [1,2,3,4,5] 1.索引取值 可以任意位置任意次数的取值 不支持无序类型的数据取值 print(l1[3]) print(l1[3]) #可以直接获取任意位 ...

  3. windows上用vs2017静态编译onnxruntime-gpu CUDA cuDNN TensorRT的坎坷之路

    因为工作业务需求的关系,需编译onnxruntime引入项目中使用,主项目exe是使用的vs2017+qt5.12. onnxruntime就不用介绍是啥了撒,在优化和加速AI机器学习推理和训练这块赫 ...

  4. 搭建漏洞环境及实战——在Linux系统中安装LANMP

    LANMP是Linux下Apache.Nginx.mysql和php的应用环境 演示的是WDLinux 命令:wget http://dl.wdlinux.cn/files/lamp_v3.tar.g ...

  5. 什么是Rabbitmq消息队列? (安装Rabbitmq,通过Rabbitmq实现RPC全面了解,从入门到精通)

    目录 Rabbitmq 一: 消息队列介绍 1.介绍 2.MQ解决了什么问题 1.应用的解耦 2.流量削峰 3.消息分发(发布订阅: 观察者模式) 4.异步消息(celery就是对消息队列的封装) 3 ...

  6. [OpenCV实战]22 使用EigenFaces进行人脸重建

    目录 1 背景 1.1 什么是EigenFaces? 1.2 坐标的变化 2 面部重建 2.1 计算新面部图像的PCA权重 2.2 使用EigenFaces进行面部重建 3 参考 在这篇文章中,我们将 ...

  7. [OpenCV实战]37 图像质量评价BRISQUE

    摄影是全世界数百万人最喜爱的爱好.毕竟,这有多难啊!用美国著名摄影师阿巴斯•黛安娜的话来说: 拍照就像深夜踮着脚尖走进厨房,偷奥利奥饼干. 拍照很容易,但是拍一张高质量的照片却很难.它需要良好的组成和 ...

  8. [机器学习] Yellowbrick使用笔记2-模型选择

    在本教程中,我们将查看各种Scikit Learn模型的分数,并使用Yellowbrick的可视化诊断工具对它们进行比较,以便为我们的数据选择最佳的模型. 代码下载 文章目录 1 使用说明 1.1 模 ...

  9. [R语言] WGCNA入门教程

    文章目录 wgcna入门-雌性小鼠肝脏表达数据的网络分析:寻找与体重有关的模块 1 数据输入和清洗 1.1 加载基因表达数据 1.2 数据清洗 1.3 加载临床特征数据 2 建设表达网络与模块检测 2 ...

  10. 聊聊MongoDB中连接池、索引、事务

    大家好,我是哪吒. 三分钟你将学会: MongoDB连接池的使用方式与常用参数 查询五步走,能活九十九? MongoDB索引与MySQL索引有何异同? MongoDB事务与ACID 什么是聚合框架? ...