当前位置: 首页 > wzjs >正文

网站备案需要关闭网站吗哈尔滨seo优化软件

网站备案需要关闭网站吗,哈尔滨seo优化软件,网站建设博敏,做物流的用什么网站配货文章目录 四数相加赎金信三数之和四数之和 四数相加 题目链接:454. 四数相加 II 这个题注意它只需要给出次数,而不是元组。所以我们可以分治。将前两个数组的加和情况使用map存储起来,再将后两个数组的加和情况使用map存储起来,ke…

文章目录

  • 四数相加
  • 赎金信
  • 三数之和
  • 四数之和

四数相加

题目链接:454. 四数相加 II

这个题注意它只需要给出次数,而不是元组。所以我们可以分治。将前两个数组的加和情况使用map存储起来,再将后两个数组的加和情况使用map存储起来,key存和,value存出现的次数。得到两个map之后,我们遍历其中一个map, 看另一个map中是否有和为0的情况,有就相加value,最后接可以得出答案。

在这种思路的基础上,我们可以继续优化代码,例如我们在统计后两个数组的同时,就已经可以将需要的和在前两个数组的map中找出来,然后把次数进行相加。

代码如下:

class Solution {public int fourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {Map<Integer,Integer> records = new HashMap<>();for(int i = 0;i < nums1.length;i++) {for(int j = 0;j < nums2.length;j++) {records.put(nums1[i] + nums2[j],records.getOrDefault(nums1[i] + nums2[j],0) + 1);}}int result = 0;for(int i = 0;i < nums3.length;i++) {for(int j = 0;j < nums4.length;j++) {Integer count = records.get(0 - nums3[i] - nums4[j]);if(count != null) result += count;}}return result;}
}

赎金信

题目链接:383. 赎金信

二十六个字母,计数,第一反应就要想到数组。解题思路如下:

  • 用数组统计第一个单词的个数
  • 然后遍历第二个单词,在数组中相应位置进行减法运算
  • 遍历数组
    • 如果存在大于0的数返回false
    • 不存在则返回true
class Solution {public boolean canConstruct(String ransomNote, String magazine) {int[] records = new int[26];for (int i = 0; i < ransomNote.length(); i++) records[ransomNote.charAt(i) - 'a']++;for (int i = 0; i < magazine.length(); i++) records[magazine.charAt(i) - 'a']--;for (int i = 0; i < records.length; i++) if(records[i] > 0 ) return false;return true;}
}

三数之和

题目链接:15. 三数之和

解题思路:

看到这一题我们肯定会不自觉地拿它和两数之和进行比较,我们是否能借助两数之和的思想来完成这一题?首先我们回顾一下两数之和的思想。在两数之和中,我们是遍历数组,每遍历一个元素,就看target - 该元素 是否已经出现过(也就是是否在hash表中),如果在直接返回,如果不在就把这个元素添加到hash表中,代表该元素出现过,为后面的元素服务。

在三数相加中,我们尝试沿用这种思路(先不直接到位,后面还会添加新逻辑):

  • 使用双层for循环遍历数组,外层循环相当于固定一个数,内层for循环沿用两数相加的逻辑
  • 初始化一个hashset,用来存已经存在的数,外层循环的以固定值不需要存
  • 内存循环遍历数组,寻找0 - nums[head]- nums[end] 是否存在于hashset中
  • 如果存在那么该数组添加到答案列表中
  • 如果不存在继续遍历
  • 外层循环每完成一次清空set
  • 最后返回答案集合

代码如下:

class Solution {public List<List<Integer>> threeSum(int[] nums) {List<List<Integer>> result = new ArrayList<>();HashSet<Integer> set = new HashSet<>();for (int i = 0; i < nums.length; i++) {for (int j = i + 1; j < nums.length; j++) {int need = -nums[i] - nums[j];if (set.contains(need)) {result.add(Arrays.asList(nums[i], nums[j], need));} else {set.add(nums[j]);}}set.clear();}return result;}
}

这个代码完成了基本的功能但是还差本题的一个重点那就是去重。

就比如题目的这个用例:[-1,0,1,2,-1,-4]
如下两种情况就会重复:

  • i指向-1,j指向1,set里有0,这组会返回
  • i指向0,j指向-1,set里有1,这组也会返回

我们可以尝试排序解决这个问题:

排序之后还是这个用例就变为:[-4,-1,-1,0,1,2]

外层循环在固定到两个-1的时候肯定会发生重复,所以我们可以添加一个条件,外层循环固定的数字和上一次相同时直接跳过:

class Solution {public List<List<Integer>> threeSum(int[] nums) {Arrays.sort(nums);List<List<Integer>> result = new ArrayList<>();HashSet<Integer> set = new HashSet<>();for (int i = 0; i < nums.length; i++) {if (i > 0 && nums[i] == nums[i - 1]) {continue;}for (int j = i + 1; j < nums.length; j++) {int need = -nums[i] - nums[j];if (set.contains(need)) {result.add(Arrays.asList(nums[i], nums[j], need));} else {set.add(nums[j]);}}set.clear();}return result;}
}

改完之后发现这个测试用例过不了:
在这里插入图片描述

原因就是当内层的两数相加满足之后,内层的下一次循环还是相同的数,那么相当于把这一组答案又加了一遍,那么我们针对这个情况进行改进:

class Solution {public List<List<Integer>> threeSum(int[] nums) {Arrays.sort(nums);List<List<Integer>> result = new ArrayList<>();HashSet<Integer> set = new HashSet<>();for (int i = 0; i < nums.length; i++) {if (i > 0 && nums[i] == nums[i - 1]) {continue;}Integer flag = null;for (int j = i + 1; j < nums.length; j++) {if(Integer.valueOf(nums[j]).equals(flag)) continue;flag = null;int need = -nums[i] - nums[j];if (set.contains(need)) {result.add(Arrays.asList(nums[i], nums[j], need));flag = nums[j];} else {set.add(nums[j]);}}set.clear();}return result;}
}

我们最后总结一下这道题:
这道题在沿用了我们前面两数之和的思想之后,会存在一个去重问题:

  • 外层重复:也就是当外层循环固定的数字和上一次相同时此次循环直接跳过
  • 内层重复:也就是当内层的两数相加满足之后,内层的下一次循环还是相同的数。这个时候我们可以在每次三数之和满足条件之后,将内层此次的值记录一下,相邻的下一次循环与此次的值一样就跳过此次内循环。

当然此题也可以使用双指针法来做,逻辑上更为简单,代码在此处不多做赘述。

四数之和

题目链接:18. 四数之和

这题使用双指针法进行解题:

  • 将数组进行排序
  • 首先使用两层的嵌套循环,固定两个数
  • 然后再使用双指针left、right确定最后两个数
  • 将四个数字相加
    • 如果大于目标,right指针左移
    • 如果小于目标,left指针右移
    • 如果达到目标,left指针右移,right指针左移
class Solution {public List<List<Integer>> fourSum(int[] nums, int target) {Arrays.sort(nums);List<List<Integer>> result = new ArrayList<>();for(int i = 0;i < nums.length;i++) {for(int j = i + 1;j < nums.length;j++) {int left = j + 1;int right = nums.length - 1;while(left < right && left < nums.length) {int sum = nums[i] + nums[j] + nums[left] + nums[right];if(sum > target) right--;else if(sum < target) left++;else {result.add(Arrays.asList(nums[i], nums[j], nums[left++],nums[right--]));}}}}return result;}
}

接下来进行去重:

在这里插入图片描述

发生这种情况就是因为外层的双层循环固定的两个数字重复,我们添加去重的代码:

class Solution {public List<List<Integer>> fourSum(int[] nums, int target) {Arrays.sort(nums);List<List<Integer>> result = new ArrayList<>();for(int i = 0;i < nums.length;i++) {if (i > 0 && nums[i] == nums[i - 1]) continue;for(int j = i + 1;j < nums.length;j++) {if (j > i + 1 && nums[j] == nums[j - 1]) continue;int left = j + 1;int right = nums.length - 1;while(left < right && left < nums.length) {int sum = nums[i] + nums[j] + nums[left] + nums[right];if(sum > target) right--;else if(sum < target) left++;else {result.add(Arrays.asList(nums[i], nums[j], nums[left++],nums[right--]));}}}}return result;}
}

这个去重的逻辑就是:

  • if (i > 0 && nums[i] == nums[i - 1]) continue; 因为数组是按大小排序的,如果第一个固定的数不变,那么其他三个数不管怎么样,都只会与target相等(这个情况已经存在需要去重)或者比target大,所以这个循环可以直接跳过
  • if (j > i + 1 && nums[j] == nums[j - 1]) continue;逻辑类似

执行之后有一个测试样例还是没过:
在这里插入图片描述
造成这个情况的原因是因为,左右指针同时内缩的时候如果元素不变也会发生重复,我们继续往里面添加去重逻辑:

class Solution {public List<List<Integer>> fourSum(int[] nums, int target) {Arrays.sort(nums);List<List<Integer>> result = new ArrayList<>();for(int i = 0;i < nums.length;i++) {if (i > 0 && nums[i] == nums[i - 1]) continue;for(int j = i + 1;j < nums.length;j++) {if (j > i + 1 && nums[j] == nums[j - 1]) continue;int left = j + 1;int right = nums.length - 1;while(left < right && left < nums.length) {long sum = (long)nums[i] + nums[j] + nums[left] + nums[right];if(sum > target) right--;else if(sum < target) left++;else {result.add(Arrays.asList(nums[i], nums[j], nums[left],nums[right]));while (right > left && nums[right] == nums[right - 1]) right--;while (right > left && nums[left] == nums[left + 1]) left++;left++;right--;}}}}return result;}
}

注意:测试用例中有一个例子考察的是四数相加的范围超出了int的最大表达值,所以四数相加的和sum要使用long来存储在这里插入图片描述

http://www.dtcms.com/wzjs/333263.html

相关文章:

  • 双语网站费用地推项目发布平台
  • 机房托管河南seo
  • 济南网站建设价格专业seo培训
  • 公司黄页企业名录在哪里查石家庄seo代理商
  • 游戏设计培训机构有哪些seo优化外包公司
  • 重庆网站建设c教育培训机构管理系统
  • 济南网站优化推广方案网络推广运营
  • WordPress公众号扫码登录seo软件简单易排名稳定
  • cve wordpress邯郸seo推广
  • 用ssh做的简单网站快手流量推广网站
  • 渭南哪家公司可以做网站网络营销的方式包括
  • 品牌建设浅谈谷歌seo推广培训班
  • 烟台教育平台网站建设seo服务
  • wordpress 字数插件提升seo排名
  • 网站备案核实单网站优化排名哪家性价比高
  • 网站自身维护百度关键词流量查询
  • wordpress 最简单模板下载seo运营专员
  • 网站搭建十大品牌公司最新热搜榜
  • 最大网站建设公司排名短网址生成网站
  • 网站建设取得实效如何外贸推广
  • 十大行情软件免费下载安装优化关键词的方法正确的是
  • 郑州营销型网站建设工作室个人网页设计作品模板
  • 做网站去青鸟学什么专业舆情分析报告模板
  • 建站行业是什么意思互联网销售怎么做
  • seo网站设计工具微软优化大师
  • 企业网站报价表网络营销的推广
  • 网页设计与制作实用教程(第3版)杭州seo搜索引擎优化
  • 龙城网站建设陕西seo快速排名
  • 网站用什么服务器全媒体运营师培训
  • 做平台网站一般有php还是js无锡营销型网站建站