第一题454.四数相加II

给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足:

0 <= i, j, k, l < n

nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0

  • 拿到题有点懵,第一时间想的是暴力,4个for循环,但想着一定会超时就没有实现直接看了题解
  • 先遍历前两个数组求出所有可能的和,存入map中,两数之和为key,出现的次数作为value
  • 再遍历后两个数组看看在map中是否有匹配(四数相加=0)的key,如果有,读取他的value,累加
public static int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {

        int sum;
Map<Integer, Integer> map = new HashMap<>();
// 把前两个数组中所有的和计算出来
for (int i = 0; i < nums1.length; i++) {
for (int j = 0; j < nums2.length; j++) {
sum = nums1[i] + nums2[j];//求出所有可能的和
if(!map.containsKey(sum)){
map.put(sum,1);//如果这个和是新的,加在map里
} else {
map.put(sum,map.get(sum)+1);//如果这个和曾在map中出现,其value+1
}
}
}
int count = 0;
//再来两个for循环遍历出后两个数组
for (int i = 0; i < nums3.length; i++) {
for (int j = 0; j < nums4.length; j++) {
sum = nums3[i] + nums4[j];
if(map.containsKey(0-sum)){
count += map.get(0-sum);//如果包含有匹配的key,读出他的value
}
}
}
return count;
}

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

第二题383. 赎金信

给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。

如果可以,返回 true ;否则返回 false 。

magazine 中的每个字符只能在 ransomNote 中使用一次。

ψ(`∇´)ψ 我的思路

  • 该说不说我真的喜欢这道题,完全get他的语境好吧
package hash;

import java.util.HashMap;
import java.util.Map; public class CanConstruct { public boolean canConstruct(String ransomNote, String magazine) {
// 先把杂志中的字母存在map中,以字母为key,次数为value
char[] mag = magazine.toCharArray();
Map<Character, Integer> map = new HashMap<>();
for (int i = 0; i < mag.length; i++) {
if(!map.containsKey(mag[i])){
map.put(mag[i],1);
} else {
map.put(mag[i],map.get(mag[i])+1);
}
}
// 遍历赎金信的每一个字母
char[] ran = ransomNote.toCharArray();
for (int i = 0; i < ran.length; i++) {
if(!map.containsKey(ran[i])){
return false;//如果赎金信中的字母没有在杂志中出现,返回false(这本不行,换一本拼吧
} else {
map.put(ran[i],map.get(ran[i])-1);//杂志中的字母用一个少一个
if(map.get(ran[i])==0){
map.remove(ran[i]);//用完就移除该字母的key
}
}
}
return true;
}
}

时间复杂度为O(n)

第三题15. 三数之和

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0。

请你返回所有和为 0 且不重复的三元组。

  • 拿到题就没什么思路,也不难为自己,直接看视频,大概看了个思路,双指针问题
  • 通过遍历数组来确定三个变量中的一个,另外两个用双指针遍历
  • 这道题要考虑的地方挺碎的,实现的时候真的是太痛苦了
package hash;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; public class ThreeSum { public static List<List<Integer>> threeSum(int[] nums) { int left, right;
List<List<Integer>> res = new ArrayList<>();
List<Integer> list = null;
Arrays.sort(nums);//给数组排序
for (int i = 0; i < nums.length-2; i++) {//遍历数组(结束条件到数组长度-2,因为后面还要left和right)
if (nums[i] > 0) {
continue;//剪枝
}
if (i > 0 && nums[i] == nums[i - 1]) {
continue;//去重
}
left = i + 1;//让left指针指向i的下一个元素的地址
right = nums.length - 1;//让right指针指向数组的最后一个元素的地址
while (left < right) {
if (nums[i] + nums[left] + nums[right] == 0) {
list = new ArrayList<>();
list.add(nums[i]);
list.add(nums[left]);
list.add(nums[right]);//把三元组存入list
res.add(list);//把list添加到res
while (left<right&&nums[left+1]==nums[left]){
left++;//去重
}
left++;
while (left<right&&nums[right-1]==nums[right]){
right--;//去重
}
right--;
} else if (nums[i] + nums[left] + nums[right] > 0) {
while (left<right&&nums[right-1]==nums[right]){
right--;//去重
}
right--;
} else if (nums[i] + nums[left] + nums[right] < 0) {
while (left<right&&nums[left+1]==nums[left]){
left++;//去重
}
left++;
}
}
}
return res;
} public static void main(String[] args) {
int[] nums = new int[]{0,0,0};
threeSum(nums);
}
}

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

  • 偶买噶,下一题是四数之和我真的栓Q了

第四题18. 四数之和

给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):

0 <= a, b, c, d < n

a、b、c 和 d 互不相同

nums[a] + nums[b] + nums[c] + nums[d] == target

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

ψ(`∇´)ψ 我的思路

  • 四数之和嘛,不就是三树之和外面包一个for循环就好啦
  • 然而到实现的时候我真的栓Q了好吧,太多临界条件,思路都写在注释里了
package hash;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; public class FourSum { public static List<List<Integer>> fourSum(int[] nums, int target) { int left, right;
List<List<Integer>> res = new ArrayList<>();
List<Integer> list = null;
Arrays.sort(nums);//给数组排序 for (int i = 0; i < nums.length; i++) {//-3是因为后面还有仨数呢
if(nums[i]>0&&target<0){
return res;
}
if (target>0 && nums[i]>0 && nums[i] > target) {
return res;//剪枝
}
if (i > 0 && nums[i] == nums[i - 1]) {
continue;//去重
}
for (int j = i+1; j < nums.length; j++) {//-2是因为后面还有两个数
//两层循环确定两个数(我也知道时间复杂度高,但没办法啊,咱不是只有双指针嘛
if (target>0 && nums[j]>0 && nums[i]+nums[j] > target) {
continue;//剪枝
}
if (j > i+1 && nums[j] == nums[j - 1]) {
continue;//去重
}
left = j + 1;//让left指针指向i的下一个元素的地址
right = nums.length - 1;//让right指针指向数组的最后一个元素的地址
while (left < right) {
if (nums[i] + nums[j] + nums[left] + nums[right] == target) {
list = new ArrayList<>();
list.add(nums[i]);
list.add(nums[j]);
list.add(nums[left]);
list.add(nums[right]);//把四元组存入list
res.add(list);//把list添加到res
while (left<right&&nums[left+1]==nums[left]){
left++;//去重
}
left++;
while (left<right&&nums[right-1]==nums[right]){
right--;//去重
}
right--;
} else if (nums[i] + nums[j] + nums[left] + nums[right] > target) {
while (left<right&&nums[right-1]==nums[right]){
right--;//去重
}
right--;
} else if (nums[i] + nums[j] + nums[left] + nums[right] < target) {
while (left<right&&nums[left+1]==nums[left]){
left++;//去重
}
left++;
}
}
}
}
return res;
}
public static void main(String[] args) {
int[] nums = new int[]{1000000000,1000000000,1000000000,100000000};
fourSum(nums,-294967296);
}
}

时间复杂度为O(n^3)

  • 一般我写代码的思路就是先把程序整个顺下来然后debug把小的地方修改修改,这题真的改到我怀疑人生

  • 这是第一次提交,找了下原因,是里层循环的一个剪枝操作,我直接返回res,造成结果不全,改成continue了之后,就多通过了4个测试用例,变成了这样

  • 不管我怎么改临界条件最后一个测试用例始终通不过,我只好又专门为他写了一段代码(私人定制)

if(nums[i]>0&&target<0){
return res;
}
  • 血条已空

总结

  • 为什么后两道双指针的题目会出现在哈希表里啊,就是看我做哈希表做的太快乐是吧

  • 今天的第一道题还是把哈希表的优点体现的挺到位的,第二题有趣但简单,后两题我是看了思路后把代码实现的,我看到双指针的章节也有这两题,希望到时候可以独立做出来

  • 看到明天的题目是字符串,哈哈开心,我现在真的需要字符串来回回血

  • 明天早点起,别再磨叽了‍♀️

代码随想录第七天| 454.四数相加II、383. 赎金信 、15. 三数之和 、18. 四数之和的更多相关文章

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

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

  2. Java实现 LeetCode 454 四数相加 II

    454. 四数相加 II 给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0. 为 ...

  3. Leetcode 454.四数相加II

    四数相加II 给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0. 为了使问题简单 ...

  4. 【哈希表】leetcode454——四数相加II

    编号454:四数相加II 给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0. 为 ...

  5. LeetCode 445. 两数相加 II(Add Two Numbers II)

    445. 两数相加 II 445. Add Two Numbers II 题目描述 给定两个非空链表来代表两个非负整数.数字最高位位于链表开始位置.它们的每个节点只存储单个数字.将这两数相加会返回一个 ...

  6. Java实现 LeetCode 445 两数相加 II

    445. 两数相加 II 给定两个非空链表来代表两个非负整数.数字最高位位于链表开始位置.它们的每个节点只存储单个数字.将这两数相加会返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会 ...

  7. day28——C/S与B/S架构、网络通信原理、osi七层协议、UDP、TCP协议、TCP的三次握手与四次挥手

    day28 C/S B/S架构 C:client 客户端 B:browse浏览器 S:server 服务端 C/S C/S架构:基于客户端与服务端之间的通信 ​ QQ.游戏.皮皮虾 ​ 优点:个性化设 ...

  8. LeetCode454. 四数相加 II

    题目 给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0. 分析 关键是如何想到用 ...

  9. Leetcode 445. 两数相加 II

    1.题目描述 给定两个非空链表来代表两个非负整数.数字最高位位于链表开始位置.它们的每个节点只存储单个数字.将这两数相加会返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会以零开头. ...

随机推荐

  1. 闭包类型(Fn,FnMut,FnOnce)和move关键字

    move关键字是强制让环境变量的所有权转移到闭包中而不管是不是发生了所有权的转移 move关键字和匿名函数是否是FnOnce没有必然联系,之和匿名函数体有关 当匿名函数体里转移了环境变量的所有权的时候 ...

  2. python编程思想及对象与类

    目录 编程思想 面向对象 面向过程 对象与类的概念 对象与类的创建 对象的实例化方法-独有数据 编程思想 1.面向对象 1.1. 面向对象前戏 案例:人狗大战 # 需求:人狗大战# 1.'创造'出人和 ...

  3. 【freertos】013-任务通知及其实现细节

    前言 参考: https://www.freertos.org/RTOS-task-notifications.html 原文:https://www.cnblogs.com/lizhuming/p/ ...

  4. OS模块中获取当前文件的绝对路径的相关方法

    os.path.realpath(__file__) 作用:获取当前执行py脚本的绝对路径(在当前工作目录下的绝对路径) __file__ : 表示当前文件的本身,一般值是当前文件的相对路径 例如: ...

  5. 技术分享 | MySQL数据误删除的总结

    欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 内容提要 用delete语句 使用drop.truncate删除表以及drop删 ...

  6. 臭名远扬之 goto 语句

    C 语言自学之 goto 语句 Dome1:以下程序实现从控制台输出1-10,使用goto语句,实现当输出完3之后跳出循环体. 1 #include <stdio.h> 2 3 int m ...

  7. Apache DolphinScheduler 源码剖析之 Worker 容错处理流程

    今天给大家带来的分享是 Apache DolphinScheduler 源码剖析之 Worker 容错处理流程 DolphinScheduler源码剖析之Worker容错处理流程 Worker容错流程 ...

  8. cad开发动态块对应的界面

    为了使设计人员更加容易的操作动态块, 应经可能对动态块的制作制定相关的规范, 如动态块的属性 => 类的属性 动态块操作名称(作为变量名,后台数据库的字段) 动态块操作描述  (作为注释,后台数 ...

  9. 认识Chrome扩展插件

    1.前言 现如今的时代,绝大多数人都要跟浏览器打交道的,说到浏览器那肯定是Chrome浏览器一家独大,具体数据请看 知名流量监测机构 Statcounter 公布了 7 月份全球桌面浏览器市场份额,主 ...

  10. Aoac唤醒的软件方案

    Aoac唤醒 这篇文章包含了Win10下的Aoac唤醒和Win11下的Aoac唤醒的不同地方,在结尾处: 从Win10时代开始,通过软件来唤醒机器是一个很常见的事情了,但是很少有文档去将如何通过AOA ...