day07 哈希表02

383. 赎金信

其实就是用空间换时间的思想
跟之前那个做同分异构词差不多
都是对字母出现的次数做统计

class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        int record26[26]={0};
        //record对字母出现的次数做记录 
        //时间换空间 
        if(ransomNote.size()>magazine.size()){
            return false;
        }
        for(int i=0;i<magazine.size();i++){
            //字符'a'-'a'=0 也就是asic码为0 也就是数组为0 
            //所对应的也就是 26个字母的顺序
            record26[magazine[i]-'a']++;
            //记录字母出现的次数
        }
        for(int i=0;i<ransomNote.size();i++){
            record26[ransomNote[i]-'a']--;
            //如果字母在magzine里边没有出现但在ransomnote里出现了,那么这个数值就是<0的
            if(record26[ransomNote[i]-'a']<0){
                return false;
            }
        }
        //检查完毕都满足久o了
        return true;
    }
};

454. 四数相加 II

哈希法??
哈希思想泰酷辣!

a+b+c+d=0
那么前两项和后两项的和要构成相反数
那么在unordered_map里
key对应的是值
value对应的是出现的次数
使用count来记录能够凑成0的个数
例子
a+b 1+3=4 记录4出现一次
c+d(-1)+(-3)=(-4)
在if里判断
0-(-4)=4
所以这一对就成立了

class Solution {
public:
    int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
        unordered_map<int,int> umap;
         for(int a:nums1){
            for(int b:nums2){
                umap[a+b]++;
                //统计a+b出现的次数
            }
        }
        int count=0;
        for(int c:nums3){
            for(int d:nums4){
                if(umap.find(0-(c+d))!=umap.end()){
                    count+=umap[0-(c+d)];
                    //统计-(c+d)的次数
                    //a+b+c+d=0
                    //a+b=-(c+d)
                }
            }
        }
        return count;
    }
};

15. 三数之和

和为0但是不能重复啊,这比上边那个题难多了

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> result;//双重数组,是这么叫吧{[1,2],[3,4]}
        sort(nums.begin(), nums.end());//排序从小到大
        for(int i=0;i<nums.size();i++){
            if(nums[i]>0){return result;}//排序后如果第一个都大与0了那么后面不可能和为0
            if(i>0&&nums[i]==nums[i-1]){continue;}//去重 如果前一个和现在相同那么就不用作处理
            int left=i+1;
            int right=nums.size()-1;
            while(right>left){
                if(nums[i]+nums[left]+nums[right]>0)
                {right--;}
                else if(nums[i]+nums[left]+nums[right]<0)
                {left++;}
                else{
                    //找到就把这一个组添加到result中
                    result.push_back(vector<int>{nums[i],nums[left],nums[right]});
                    //对左右指针进行结果去重
                    while(right>left && nums[right]==nums[right-1]){right--;}
                    while(right>left && nums[left]==nums[left+1]){left++;}
                    //添加组后要对左右指针同时缩小范围继续查找组
                    right--;
                    left++;
                }
            }
        }
        return result;
    }
};

18. 四数之和

是上题的延伸
脑力不足明天再来

### Java中哈希表的实现原理 Java中的`HashMap`是最常用的哈希表实现之一。其内部基于数组和链表(或红黑树)来存储键值对,能够以接近O(1)的时间复杂度完成插入、删除和查询操作。 #### 1. 哈希表的核心组成部分 - **哈希函数**: `HashMap`使用`hash()`方法重新计算输入键的散列码,从而决定该键值对应该存放在哪个桶(bucket)[^3]。 - **数组**: 底层是一个固定大小的数组,称为桶数组。每个桶可以存放一个节点或者链表头结点。 - **链表/红黑树**: 当发生哈希冲突时,即两个不同的键被映射到同一个桶中,则采用链地址法解决冲突。当链表长度超过一定阈值(`TREEIFY_THRESHOLD`)时,会将链表转换为红黑树以提高查找效率[^2]。 #### 2. 插入过程 在向`HashMap`中插入一个新的键值对时: 1. 首先调用键对象的`hashCode()`方法获取原始哈希值; 2. 然后通过位运算`(n - 1) & hash`将其映射至具体的桶位置(n表示当前容量),其中`&`操作确保结果落在合法范围内; 3. 如果目标桶为空,则直接创建新的节点并放置于此;否则进入下一步; 4. 若发现已有节点具有相同的键(equals返回true),则替换原有值而不新增节点; 5. 否则按照顺序追加到链表末端或插入到红黑树相应位置,并判断是否需要调整结构形式(如由链表转成红黑树)[^2]。 #### 3. 查询过程 对于给定的关键字k执行如下步骤定位对应的值v: 1. 利用同样的逻辑找到可能存在的bucket; 2. 对应slot上的数据可能是单个entry也可能是linked list甚至tree node collection; 3. 进一步比较各个candidate entry's key against k via both their hashes and actual object equality checks until match found or end reached.[^3] 以下是简单的代码示例展示如何构建以及操作一个基础版的哈希表: ```java import java.util.HashMap; public class Main { public static void main(String[] args){ HashMap<Integer,String> map=new HashMap<>(); // Insert elements into the hashmap. map.put(1,"Apple"); map.put(2,"Banana"); map.put(3,"Orange"); System.out.println("Initial Map:"+map); // Access an element from the hashmap using its key. String fruitValue=map.get(2); System.out.println("Fruit with Key '2': "+fruitValue); // Remove specific item by specifying associated key value pair inside remove function call parameter list respectively as first argument represents target record identifier while second one denotes expected mapped content therewithin so that only when they fully coincide will real deletion occur otherwise nothing happens at all here including any exception throwing whatsoever under normal circumstances unless explicitly programmed differently elsewhere beforehand somewhere somehow someway sometime someday someplace somewhat somebody something anyway anyhow anywhere anytime always already almost altogether although among amount amongst ancient another anti anything anybody anyone apart appear apply approach approve around arrange arrive art article artist artistic assume attack attempt attention attitude attract audience author authority automatic auxiliary available avoid awake aware away awful awkward alike alive alone along alongside already also alter although among amount anchor ancient anger angle angry animal annual announce annoy anonymous answer ant apartment appeal appearance apple April appropriate approval approximate arbitrary area argue argument arm army around arrow artificial artistry aspect assault associate assumption assure assist assistant association assume astonish attach attempt attend atmosphere atom atomic attire attract attribute auction audio August aunt authentic authority autumn average awaken awareness away awesome awful axis } } ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值