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

微课做动画的网站seo品牌优化百度资源网站推广关键词排名

微课做动画的网站,seo品牌优化百度资源网站推广关键词排名,托育项目建设背景及必要性,建设网站花都区题目 给你一个包含 n 个整数的数组 nums#xff0c;判断 nums 中是否存在三个元素 a#xff0c;b#xff0c;c #xff0c;使得 a b c 0 #xff1f;请你找出所有满足条件且不重复的三元组。 注意#xff1a; 答案中不可以包含重复的三元组。 示例#xff1a; 给定数…题目 给你一个包含 n 个整数的数组 nums判断 nums 中是否存在三个元素 abc 使得 a b c 0 请你找出所有满足条件且不重复的三元组。 注意 答案中不可以包含重复的三元组。 示例 给定数组 nums [-1, 0, 1, 2, -1, -4] 满足要求的三元组集合为 [ [-1, 0, 1], [-1, -1, 2] ] 思路  这道题与前面提到的两数之和以及四数之和Ⅱ在题意上非常类似大家第一想法可能就是使用哈希法来处理但是事实证明哈希解法此时并不是明智的选择。 哈希解法 两层for循环就可以确定 a 和b 的数值了可以使用哈希法来确定 0-(ab) 是否在 数组里出现过其实这个思路是正确的但是我们有一个非常棘手的问题就是题目中说的不可以包含重复的三元组。 把符合条件的三元组放进vector中然后再去重这样是非常费时的很容易超时也是这道题目通过率如此之低的根源所在。 去重的过程不好处理有很多小细节如果在面试中很难想到位。 时间复杂度可以做到O(n^2)但还是比较费时的因为不好做剪枝操作。 哈希法C代码: class Solution { public:vectorvectorint threeSum(vectorint nums) {vectorvectorint result;sort(nums.begin(), nums.end());// 找出a b c 0// a nums[i], b nums[j], c -(a b)for (int i 0; i nums.size(); i) {// 排序之后如果第一个元素已经大于零那么不可能凑成三元组if (nums[i] 0) {break;}if (i 0 nums[i] nums[i - 1]) { //三元组元素a去重continue;}unordered_setint set;for (int j i 1; j nums.size(); j) {if (j i 2 nums[j] nums[j-1] nums[j-1] nums[j-2]) { // 三元组元素b去重continue;}int c 0 - (nums[i] nums[j]);if (set.find(c) ! set.end()) {result.push_back({nums[i], nums[j], c});set.erase(c);// 三元组元素c去重} else {set.insert(nums[j]);}}}return result;} }; 时间复杂度: O(n^2)空间复杂度: O(n)额外的 set 开销 可以看到剪枝逻辑非常复杂尤其是去重的逻辑判断上所以这里引出更加好理解并且效率高的双指针法。 双指针法 其实这道题目使用哈希法并不十分合适因为在去重的操作中有很多细节需要注意在面试中很难直接写出没有bug的代码。而且使用哈希法 在使用两层for循环的时候能做的剪枝操作很有限虽然时间复杂度是O(n^2)也是可以在leetcode上通过但是程序的执行时间依然比较长 。 这道题目使用双指针法 要比哈希法高效一些那么来讲解一下具体实现的思路。 动画效果如下 拿这个nums数组来举例首先将数组排序然后有一层for循环i从下标0的地方开始同时定一个下标left 定义在i1的位置上定义下标right 在数组结尾的位置上。 依然还是在数组中找到 abc 使得a b c 0我们这里相当于 a nums[i]b nums[left]c nums[right]。 接下来如何移动left 和right呢 如果nums[i] nums[left] nums[right] 0 就说明 此时三数之和大了因为数组是排序后了所以right下标就应该向左移动这样才能让三数之和小一些。 如果 nums[i] nums[left] nums[right] 0 说明 此时 三数之和小了left 就向右移动才能让三数之和大一些直到left与right相遇为止。 时间复杂度O(n^2)。 C代码代码如下 class Solution { public:vectorvectorint threeSum(vectorint nums) {vectorvectorint result;sort(nums.begin(), nums.end());// 找出a b c 0// a nums[i], b nums[left], c nums[right]for (int i 0; i nums.size(); i) {// 排序之后如果第一个元素已经大于零那么无论如何组合都不可能凑成三元组直接返回结果就可以了if (nums[i] 0) {return result;}// 错误去重a方法将会漏掉-1,-1,2 这种情况/*if (nums[i] nums[i 1]) {continue;}*/// 正确去重a方法if (i 0 nums[i] nums[i - 1]) {continue;}int left i 1;int right nums.size() - 1;while (right left) {// 去重复逻辑如果放在这里000 的情况可能直接导致 rightleft 了从而漏掉了 0,0,0 这种三元组/*while (right left nums[right] nums[right - 1]) right--;while (right left nums[left] nums[left 1]) left;*/if (nums[i] nums[left] nums[right] 0) right--;else if (nums[i] nums[left] nums[right] 0) left;else {result.push_back(vectorint{nums[i], nums[left], nums[right]});// 去重逻辑应该放在找到一个三元组之后对b 和 c去重while (right left nums[right] nums[right - 1]) right--;while (right left nums[left] nums[left 1]) left;// 找到答案时双指针同时收缩right--;left;}}}return result;} }; 时间复杂度: O(n^2)空间复杂度: O(1) 注意点 a的去重 说到去重其实主要考虑三个数的去重。 a, b ,c, 对应的就是 nums[i]nums[left]nums[right] a 如果重复了怎么办a是nums里遍历的元素那么应该直接跳过去。 但这里有一个问题是判断 nums[i] 与 nums[i 1]是否相同还是判断 nums[i] 与 nums[i-1] 是否相同。 有人可能想这不都一样吗。 其实不一样 都是和 nums[i]进行比较是比较它的前一个还是比较它的后一个。 如果我们的写法是 这样 if (nums[i] nums[i 1]) { // 去重操作continue; }那我们就把 三元组中出现重复元素的情况直接pass掉了。 例如{-1, -1 ,2} 这组数据当遍历到第一个-1 的时候判断 下一个也是-1那这组数据就pass了。 我们要做的是 不能有重复的三元组但三元组内的元素是可以重复的 所以这里是有两个重复的维度。 那么应该这么写 if (i 0 nums[i] nums[i - 1]) {continue; }这么写就是当前使用 nums[i]我们判断前一位是不是一样的元素在看 {-1, -1 ,2} 这组数据当遍历到 第一个 -1 的时候只要前一位没有-1那么 {-1, -1 ,2} 这组数据一样可以收录到 结果集里。 这是一个非常细节的思考过程。 b与c的去重 很多人写本题的时候去重的逻辑多加了 对right 和left 的去重代码中注释部分 while (right left) {if (nums[i] nums[left] nums[right] 0) {right--;// 去重 rightwhile (left right nums[right] nums[right 1]) right--;} else if (nums[i] nums[left] nums[right] 0) {left;// 去重 leftwhile (left right nums[left] nums[left - 1]) left;} else {} }但细想一下这种去重其实对提升程序运行效率是没有帮助的。 拿right去重为例即使不加这个去重逻辑依然根据 while (right left) 和 if (nums[i] nums[left] nums[right] 0) 去完成right-- 的操作。 多加了 while (left right nums[right] nums[right 1]) right--; 这一行代码其实就是把 需要执行的逻辑提前执行了但并没有减少 判断的逻辑。 最直白的思考过程就是right还是一个数一个数的减下去的所以在哪里减的都是一样的。 所以这种去重 是可以不加的。 仅仅是 把去重的逻辑提前了而已。
http://www.zqtcl.cn/news/554878/

相关文章:

  • a5建站无限动力网站
  • 南京网站建设王道下拉??怎么做免费网站推
  • WordPress站群 管理icp备案网站管理员有负责吗
  • 智慧团建官方网站登录做网站网站的虚拟空间
  • 自己做网站成本推广代理平台
  • wamp搭建多个网站网站设计方面有什么公司
  • 九江集团网站建设app广告对接平台
  • 个人网页网站制作模板搜索引擎营销经典案例
  • 北京自助建站系统思茅区建设局网站
  • 国外被动收入网站做的好的成都网站建设 川icp备
  • 网站的微信推广怎么做php在电子商务网站建设中的应用研究 戴书浩
  • 中山做网站有什么做logo网站
  • 建设网站要什么手续义乌简游网络科技有限公司
  • 深圳做企业网站的音乐网站设计
  • 互联网网站如何做菜鸟教程自学网
  • 网站模板上传工具网站报名照片怎么做
  • 做网站如何备案东城做企业网站多少钱
  • 建设手机网站的目的广告制作行业发展前景
  • 手工艺品网站建设目的长春有哪些网络设计公司
  • 重庆建设工程招标网站淮南58同城网
  • 有域名在本机上做网站psd素材
  • 做拍拍拍拍网站网站宣传的劣势
  • 建设银行官方网站诚聘英才亚马逊店铺出售网站
  • 佛山房地产网站建设万网域名查询接口
  • 新建的网站必须要备案吗优购物网
  • 陕西省住房和城乡建设厅官方网站智能网站建设制作
  • 英语故事网站建设镇江大港信息港
  • 接单做一个网站多少钱商河网站建设
  • 网站建设s南昌网站建设服务
  • 免费的素材网站有哪些重庆网页设计公司排名