IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 随想录一刷Day07——哈希表 -> 正文阅读

[数据结构与算法]随想录一刷Day07——哈希表

Day07_哈希表

6. 四数相加 II

454. 四数相加 II
思路:

首先观察数据范围-228 <= nums1[i], nums2[i], nums3[i], nums4[i] <= 228,说明四个数相加不会爆int
1 <= n <= 200,说明如果纯暴力四层循环会超过1s, O ( n 4 ) O(n^4) O(n4)
考虑到前面做的题,将一个数组中的数据全部放到集合里,利用另一个数组中的元素去集合里判断。

  1. 将四个长度为n的数组组合成两个长度为n^2的数组
  2. 然后将一个数组放入哈希表,遍历另一个数组判断其相反数是否在哈希表中。不使用集合是因为这里可能出现num1[i] + num2[j] == nums1[k] + nums2[l]的情况,使用集合的话就会使答案统计不全。

时间复杂度为 O ( n 2 ) O(n^2) O(n2)

class Solution {
public:
    int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
        unordered_map<int, int> my_map;
        int count = 0;
        for (int a : nums1) {
            for (int b : nums2) {
                my_map[a + b]++; // 将数组1,2合并,并建立哈希表
            }
        }
        for (int c : nums3) {
            for (int d : nums4) {
                count += my_map[-c-d]; // 将数组3,4合并,并在哈希表中找其相反数
            }
        }
        return count;
    }
};

7. 赎金信

383. 赎金信
思路:

只要ransomeNote中的字母字magezine中全都出现过,并且magezine中对应字母的数量也够即可。
由于只有26个小写字母,可以直接映射到数字下标0~25中建立哈希表。

  1. 利用magezine中的字母建立哈希表
  2. 遍历ransmoeNote中的字母,每遍历一个就消耗一个哈希表中的字母,如果哈希表中的字母不够用,则返回false;够用就返回true
class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        int my_map[26] = {0};
        for (char mage : magazine) {
            my_map[mage - 'a']++;
        }
        for (char ran : ransomNote) {
            if (my_map[ran - 'a'] <= 0) return false;
            my_map[ran - 'a']--;
        }
        return true;
    }
};

8. 三数之和

15. 三数之和

数据范围:
3 <= nums.length <= 3000
-105 <= nums[i] <= 105

思路:

根据数据范围判断,三数之和不会爆int,但是如果纯暴力三层循环的话会超时, O ( n 3 ) O(n^3) O(n3)
太菜了,经过一波思考,唯一能想到的就是看能不能通过排个序,整个正负数划分之类的,但是想不明白。
看题解!
利用双指针,固定一个指针i用来遍历整个数组,在区间(i, nums_size - 1]内建立两个指针,left在区间最左端向右动,right在区间最右端向左动,如此寻找目标三元组可做到不重不漏。
上述方法的复杂度为 O ( n 2 ) O(n^2) O(n2)
需要考虑三个指针位置的去重问题,代码如下

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> ans;
        int nums_size = nums.size();
        sort(nums.begin(), nums.end()); // 升序排列
        for (int i = 0; i < nums_size; ++i) {
            if (nums[i] > 0) return ans; // 第一个数最小,如果此数大于0,三数之和不可能为0
            if (i > 0 && nums[i] == nums[i - 1]) continue; // 第一个数去重
            int left = i + 1;
            int right = nums_size - 1;
            while (left < right) { // nums[left] 和 nums[right]可以相同,但是下标不能相同
                if (nums[i] + nums[left] + nums[right] < 0) left++; // 三数之和小了,固定位置i和right不动,left右移
                else if (nums[i] + nums[left] + nums[right] > 0) right--; // 三数之和大了,固定位置i和left不动,right左移
                else {
                    ans.push_back(vector<int> {nums[i], nums[left], nums[right]});
                    /*
                        如果出现左边两个数相同的结果,已经加入ans了,不能出现第二次
                        left 与 left+1 比较,
                        并在最后添加一个left++,移动到第一个不相同的数字位置
                    */
                    while (left < right && nums[left] == nums[left + 1]) left++;
                    /*  对于right,相同的值没有意义,因为之前已经得到了该值的所有答案组合
                        不和 right+1 比较是避免第一次判断越界,所以和 right-1 比较,
                        并在最后添加一个 right--,将right指针移动到第一个没有出现过的值上
                    */
                    while (left < right && nums[right] == nums[right - 1]) right--; 
                    left++;
                    right--;
                }
            }
        }
        return ans;
    }
};

9. 四数之和

18. 四数之和
思路:

和三数之和一个思路,还是双指针,只不过把固定的指针从一个i变成了一个ij的排列组合。然后在区间[j+1, nums_size-1]内用双指针遍历。

提交的时候记得把cout注释掉,不然显示超时了,自己debug半天还不知道咋回事

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int>> ans;
        sort(nums.begin(), nums.end());
        int nums_size = nums.size();
        for (int i = 0; i < nums_size - 1; ++i) {
            if (nums[i] > target && nums[i] > 0) break; // 一级剪枝
            if (i > 0 && nums[i] == nums[i - 1]) continue; // nums[i]去重
            for (int j = i + 1; j < nums_size; ++j) {
                long static_num = nums[i] + nums[j];
                if (static_num > target && static_num > 0) break; // 二级剪枝
                if (j > i + 1 && nums[j] == nums[j - 1]) continue; // nums[j]去重
                int left = j + 1;
                int right = nums_size - 1;
                while (left < right) {
                    // cout << static_num << " " << i << " " << j << " " << left << " " << right << endl;
                    if (static_num + nums[left] + nums[right] < target) left++;
                    else if (static_num + nums[left] + nums[right] > target) right--;
                    else {
                        ans.push_back(vector<int>{nums[i], nums[j], nums[left], nums[right]});
                        while (left < right && nums[left] == nums[left + 1]) left++;
                        while (left < right && nums[right] == nums[right - 1]) right--;
                        left++;
                        right--;
                    }
                }
            }
        }
        return ans;
    }
};
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-09-30 01:12:58  更:2022-09-30 01:14:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 18:17:55-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计