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

网站a记录吗渭南最新防疫信息

网站a记录吗,渭南最新防疫信息,网站建设学生选课课程设计报告,推荐30个国外优秀的设计教程网站目录 1.题目 2.分析 算法 方法1:使用set去重 版本1代码 方法2:利用数组的有序性来去重 操作left和right 操作bound 其他问题 1.如果和<0,left后需要去重吗? 同理,如果和>0,right--后需要去重吗? 2.如果和0,是只移动left还是只移动right还是两个指针都移动?…

目录

1.题目

2.分析

算法

方法1:使用set去重

版本1代码

方法2:利用数组的有序性来去重

操作left和right

操作bound

其他问题

1.如果和<0,left++后需要去重吗? 同理,如果和>0,right--后需要去重吗?

2.如果和==0,是只移动left还是只移动right还是两个指针都移动?

如果只移动其中任何一个指针

如果一次性移动两个指针

版本2代码

版本2代码的小优化

3.验证指针移动的效率问题

和为0时移动动两个指针

只移动其中任何一个指针


1.题目

https://leetcode.cn/problems/1fGaJU/description/

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 abc 使得 a + b + c = 0 ?请找出所有和为 0 且 不重复 的三元组。

示例 1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]

示例 2:

输入:nums = []
输出:[]

示例 3:

输入:nums = [0]
输出:[]

提示:

  • 0 <= nums.length <= 3000
  • -10^5 <= nums[i] <= 10^5

注意:本题与主站 15 题相同:15. 三数之和 - 力扣(LeetCode)

2.分析

算法

从L36.【LeetCode题解】查找总价格为目标值的两个商品(剑指offer:和为s的两个数字) (双指针思想,内含详细的优化过程)文章得到的经验来看,显然先排序,利用有序数组的单调性使用三指针:将其中一个指针bound固定不动,使用左右指针left和right来移动,如果满足题目条件,就将{nums[left],nums[right],nums[bound]}尾插到类型为vector<vector<int>> 的ret中

移动的方法:

1.如果nums[left]+nums[right]+nums[bound]<0,需要增大结果,left++

2.如果nums[left]+nums[right]+nums[bound]<0,需要减小结果,right--

但题目还要求了三元组不能重复,所以需要对返回的结果进行去重操作

★注意题目的细节:0 \leq nums.length \leq 3000,nums.length可以为0,直接返回{ },同理nums.length为1或2时,也直接返回{ },这个单独处理

但https://leetcode.cn/problems/3sum/题的nums.length最小取3,这里要注意

方法1:使用set去重

之前在CC42.【C++ Cont】STL库的红黑树set的使用文章提到过:

"set与multiset 的区别:set不能相同元素,multiset可以存相同的元素,其余的使用方式完全一致.因此,可以用set来给数据去重"

版本1代码
class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {set<vector<int>> tmp;vector<vector<int>> ret;if (nums.size()==0)return ret;sort(nums.begin(),nums.end());for (int bound=nums.size()-1;bound>1;bound--){int left=0;int right=bound-1;while (left<right){int sum=nums[left]+nums[right]+nums[bound];if (sum>0)right--;else if (sum<0)left++;else//sum==0{if (tmp.count({nums[left],nums[right],nums[bound]})==0){tmp.insert({nums[left],nums[right],nums[bound]});ret.push_back({nums[left],nums[right],nums[bound]});} left++;   //break;}}}return ret;}
};

提醒:注意到break;语句被注释掉了,这里找到一个不能直接退出循环! 需要找到所有满足条件的三元组

提交结果:

*面试时不建议使用此法来去重,没有达到训练的要求

方法2:利用数组的有序性来去重

例如给定以下数组[-1,0,1,2,1,-4],排过序后为[-4,-1,0,1,1,2]

操作left和right

以下两种情况均满足要求:

显然需要去重,right前后都是-1,需要跳过重复的情况,可以比较right前后的值是否相同,使用循环来跳过所有重复的情况,因为重复的元素都是在一起的,有以下代码:

right--;
//right--后,right之前为right+1,比较--前和--后right指向的值是否相同
while(nums[right]==nums[right+1])right--;

但这样写会有潜在的问题:right可能会越过left导致left<=right,甚至是对数组越界访问,因此还需要一个条件left>right

right--;
while(nums[right]==nums[right+1] && left<right)right--;

同理left++后也有可能指向相同的值,代码如下:

left++;
while(nums[left]==nums[left-1] && left<right)left++;

left>right这个思想曾经在120.【C语言】数据结构之快速排序(详解Hoare排序算法)文章中提到过的单趟排序的代码,内循环由两个条件限制:

	//单趟快速排序int key_i = left;while (left < right){//由于key_i==left,因此right指针先走//右边找小while (left < right && arr[right] >= arr[key_i]){right--;}//左边找大while (left < right && arr[left] <= arr[key_i]){left++;}Swap(&arr[left], &arr[right]);}Swap(&arr[key_i], &arr[left]);
操作bound

注意bound++后也有可能指向和之前相同的值,因此也要对bound去重,这里容易忽视

其次bound不能一直++,也有可能越界,bound的最大取值为 nums.size()-3,要为nums[left]和nums[right]留空位

bound++;
while(nums[bound-1]==nums[bound] && bound<nums.size()-2)bound++;
其他问题
1.如果和<0,left++后需要去重吗? 同理,如果和>0,right--后需要去重吗?

答:去重指的是:在三元组和为0的情况下且至少有两个三元组的元素相同时,需要去重,前提是和为0,如果>0或<0,不需要去重

2.如果和==0,是只移动left还是只移动right还是两个指针都移动?

从正确性上来说都没有问题,下面进行分析:

如果只移动其中任何一个指针

这里以left为例子:因为要去重,所以要移动到和之前指向的值有所不同的位置,当left移动到新的位置时,和必然不为0,可以交给下一次循环时判断并移动指针

以[-5,0,1,1,2,2,3,3,4,4]为例分析: 

 

如果一次性移动两个指针

仍然以[-5,0,1,1,2,2,3,3,4,4]为例分析:

感觉上一次性移动两个指针效率比只移动其中任何一个指针要高一点,在文章的最后会验证此想法

版本2代码
class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {if (nums.size()<3)return {};sort(nums.begin(),nums.end());vector<vector<int>> ret;int left,right,bound=0;while(bound<nums.size()-2){left=bound+1;right=nums.size()-1;while (left<right){if (nums[bound]+nums[left]+nums[right]>0)right--;             else if (nums[bound]+nums[left]+nums[right]<0)left++;else{ret.push_back({nums[bound],nums[left],nums[right]});left++;while(nums[left]==nums[left-1]&&left<right)left++;right--;while(nums[right]==nums[right+1] && left<right)right--;}}bound++;while(nums[bound-1]==nums[bound]&&bound<nums.size()-2)bound++;}return ret;}
};

提交结果:

版本2代码的小优化

当nums[bound]>0时可以直接退出循环,一定找不到符合要求的三元组,直接返回即可,此操作可以加在循环的最后:

while(bound<nums.size()-2)
{//......while (left<right){if (nums[bound]+nums[left]+nums[right]>0)right--;             else if (nums[bound]+nums[left]+nums[right]<0)left++;else{//......}}bound++;while(nums[bound-1]==nums[bound]&&bound<nums.size()-2)bound++;if (nums[bound]>3)return ret;
}

3.验证指针移动的效率问题

可以写个测试程序:统计三个指针bound、left和right的移动次数:

到leetcode上获取数据量大的测试用例,由于在leetcode上提交时网站会报告没有通过的测试用例,因此可以通过写条件判断:指定获取150个元素以上的测试用例:

由于测试代码较大,这里给出下载链接,提取码: hhrmhttps://pan.baidu.com/s/1i5juwMMvY4SXrqT-OOWKOw?pwd=hhrm

和为0时移动动两个指针

运行结果:

只移动其中任何一个指针

运行结果:

其实没有区别,和为0时指针移动的次数是一样的,都是4461737次


文章转载自:

http://7rMEBoYt.jgmdr.cn
http://cfCDKPip.jgmdr.cn
http://zADxF27O.jgmdr.cn
http://qIhgTghS.jgmdr.cn
http://5sqqao2D.jgmdr.cn
http://3ZuE2tmH.jgmdr.cn
http://gGWvrDWL.jgmdr.cn
http://HIckxa3I.jgmdr.cn
http://xq8C0k1T.jgmdr.cn
http://IiZ3R85M.jgmdr.cn
http://yFMqDit8.jgmdr.cn
http://Cg2CoodF.jgmdr.cn
http://xtS1hG5a.jgmdr.cn
http://jgN0IyP6.jgmdr.cn
http://Ky5eiv4F.jgmdr.cn
http://jKeyTErd.jgmdr.cn
http://c97mv51M.jgmdr.cn
http://HaMsZqyQ.jgmdr.cn
http://E2IPHLde.jgmdr.cn
http://DaxK0pUZ.jgmdr.cn
http://91wAzj9s.jgmdr.cn
http://w5GL0D1O.jgmdr.cn
http://SfpSuL8y.jgmdr.cn
http://OIZyS3uO.jgmdr.cn
http://pjsBI8vL.jgmdr.cn
http://OtO9s11e.jgmdr.cn
http://OkBVlvbS.jgmdr.cn
http://FEh6ptCx.jgmdr.cn
http://dfH8C8Gd.jgmdr.cn
http://QdyLAqhe.jgmdr.cn
http://www.dtcms.com/wzjs/683615.html

相关文章:

  • 公司网站建设调研背景黑猫会活动策划网站
  • 鄂尔多斯 网站制作个人建设网站难吗
  • 经销商怎么做网站外国网站设计素材
  • 网站可以自己维护吗vi设计主题品牌
  • 办公室门户网站建设和管理工作wordpress网站页脚
  • 公司网站建设的宁波建设网证书查询平台
  • 青岛做模板网站的公司房地产信息查询网
  • 简易app软件seo平台
  • 莘县网站织梦网站防黑怎么做
  • 深圳flash网站建设北京城市建设档案馆网站
  • 同个网站可以做多个外链吗wordpress页面链接404
  • 交通建设工程质量监督局网站网站 营销策略
  • 中小企业网络构建长春seo公司
  • 酒店网站设计方案山东川畅科技做网站多少钱
  • html判断域名 然后再跳转到网站环保局 网站建设
  • 手机搞笑网站模板下载安装做网站银川
  • 北京搬家公司24小时服务电话seo短视频网页入口引流网址
  • 安丘建设网站上海有哪几家做新房的网站
  • 网站制作软件工程师网上购物商城源代码
  • 网站后台编辑框无法显示重庆网站设计生产厂家
  • 医院网站建设计划做推广便宜的网站
  • 影楼网站模版工业设计公司有哪些
  • 西安地区专业做网站公司做一个网站加优化排名得多少钱
  • 江苏省通信建设交易中心网站seo服务套餐
  • 网站新媒体建设方案前端网页代码模板
  • 织梦首饰网站模板网站运营是什么岗位
  • 莆田网站建设方法wordpress彩色框
  • 软件公司都是帮别人做网站么网站集约化建设意见
  • 专业网站建设知识wordpress 赏
  • 网站建网站建设设大诚当道设计公司