k<<=1具体是什么意思?

给大家推荐个靠谱的公众号程序员探索之路,大家一起加油

首先说明一个东西机器:0,1序列。

位移操作建立在补码的基础之上。
1.无符号位移
无符号位移:左移,高位截去,低位补零。右移,高位补零,低位截去。
举个无符号位移的例子:
假设int i=3:转换成原码:0000 0011
i<<=1则表示将以上的二进制码往左移动一位,低位补零。结果是:0000 0110即十进制的6.
所以无符号位移有结论:i<<=n  等价于  i=i*(2的n次方);  i>>=n  等价于  i=i/(2的n次方)(n>=0)(暂不考虑溢出的情况)。

2.带符号位移(暂不考虑溢出的情况)
      带符号位移正数和无符号位移没有区别(因为正数的补码和反码,只是在原码前加正数标识位0)。
      带符号负数位移则不同(因为负数的补码是反码加一取得,反码是原码按位取反再在高位加上标识位1得到),左移是符号位不变,整体左移,低位补0,右移是符号位不变,整体右移,高位补1

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
nums) { // 在这里开始你的代码优化 } 的时间复杂度。 A:Sure!首先,我们需要分析一下原始的 threeSum 函数的时间复杂度。它的主要操作是对给定数组 nums 进行排序,这个操作的时间复杂度为 O(nlogn)。其次,我们需要枚举每个位置作为三元组的第一个元素,然后在它的右侧找到两个数使得三数之和为 0,这个过程的时间复杂度为 O(n^2)。由此,我们可以得出原始 threeSum 函数的时间复杂度为 O(n^2logn)。 那么如何优化呢?一个显然的思路是减少排序所花费的时间。考虑到问题的特性,我们可以先将数组进行去重,然后将它分为三类:负数、正数和零。这样,我们就可以不用对整个数组排序,而是只需对负数和正数进行排序。这个过程的时间复杂度为 O(nlogn)。 接下来,我们可以将枚举和查找两个操作结合起来。具体来说,我们可以把枚举操作放在排序的过程中,这样可以有效减少查找的次数。具体实现时,我们可以先对负数和零进行枚举,然后在正数中查找。注意到正数中的元素过大,所以我们需要用二分查找来加速这个过程。这个过程的时间复杂度为 O(n^2logn)。 综上所述,我们可以得到下面的代码: class Solution { public: vector&lt;vector&lt;int>> threeSum(vector&lt;int>& nums) { vector&lt;vector&lt;int>> res; sort(nums.begin(), nums.end()); int n = nums.size(); for (int i = 0; i &lt; n - 2; i++) { // 去重 if (i > 0 && nums[i] == nums[i - 1]) continue; // 分类讨论 if (nums[i] > 0) break; int l = i + 1, r = n - 1; while (l &lt; r) { int sum = nums[i] + nums[l] + nums[r]; if (sum &lt; 0) l++; else if (sum > 0) r--; else { res.push_back({nums[i], nums[l], nums[r]}); // 去重 while (l &lt; r && nums[l] == nums[l + 1]) l++; while (l &lt; r && nums[r] == nums[r - 1]) r--; l++; r--; } } } return res; } }; 该算法的时间复杂度为 O(n^2logn),比原算法性能有了明显提升。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值