- 本人的LeetCode账号:魔术师的徒弟,欢迎关注获取每日一题题解,快来一起刷题呀~
- 本人Gitee账号:路由器,欢迎关注获取博客内容源码。
1 转换数字的最少位翻转次数
![](https://router-picture-bed.oss-cn-chengdu.aliyuncs.com/img/20220403153740.png)
本题思路比较简单,利用按位与和右移运算即可。
class Solution {
public:
int minBitFlips(int start, int goal)
{
int res = 0;
int i = 0;
while (goal >> i != 0 || start >> i != 0)
{
if ((start >> i & 1) != (goal >> i & 1))
{
++res;
}
++i;
}
return res;
}
};
2 数组的三角和
![](https://router-picture-bed.oss-cn-chengdu.aliyuncs.com/img/20220403154300.png)
思路很简单,可以优化的地方就是:本题可以节约空间复杂度,在原地操作,因为每次的值都是赋值在nums[i]
,nums[i + 1]
不会受影响。
class Solution {
public:
int triangularSum(vector<int>& nums)
{
int cnt = nums.size() - 1;
int n = cnt;
while (cnt--)
{
for (int i = 0; i < n; ++i)
{
nums[i] = (nums[i] + nums[i + 1]) % 10;
}
--n;
}
return nums[0];
}
};
考场上,我是不断开新vector
做的,不过好像速度并没有像我想的那样,减少了开数组申请内存、新旧数组拷贝的时间,快很多。
![](https://router-picture-bed.oss-cn-chengdu.aliyuncs.com/img/20220403154835.png)
3 选择建筑的方案数
![](https://router-picture-bed.oss-cn-chengdu.aliyuncs.com/img/20220403155238.png)
本题可以用动态规划求解,但是更快的方法是前缀和。
如果要获得一个区间里头的信息情况,比如有多少个1啊这样的,如果和我有一样没学过线段树,我们就可以用前缀和来处理。
回到本题,我们思考,对于下标为i的字符s[i]
,如果它是'0'
,那么它想称为建筑必须得是左边加'1'
右边加'1'
,那么以它为中心的建筑的方案数等于i
左边的'1'
的个数 * i
右边的'1'
的个数,如果它是'0'
则正好相反,所以我们需要获得任意一个区间中'0'
或'1'
的个数,这就很适合前缀和登场。
class Solution {
public:
typedef long long LL;
long long numberOfWays(string s)
{
int n = s.size();
vector<int> cnt1(n);
vector<int> cnt0(n);
cnt1[0] = (s[0] == '1');
cnt0[0] = (s[0] == '0');
for (int i = 1; i < n; ++i)
{
cnt1[i] = cnt1[i - 1] + (s[i] == '1');
cnt0[i] = cnt0[i - 1] + (s[i] == '0');
}
LL res = 0;
for (int i = 1; i < n; ++i)
{
if (s[i] == '1')
{
res += (LL)cnt0[i] * (cnt0[n - 1] - cnt0[i]);
}
else
{
res += (LL)cnt1[i] * (cnt1[n - 1] - cnt1[i]);
}
}
return res;
}
};
4 扯淡
为啥没有第四题,因为第四题不会。