T1:一个 整数的 二进制形式中 奇数位上bit==1 和 偶数 位上bit==1 分别计数
给你一个 正 整数 n
。
用 even
表示在 n
的二进制形式(下标从 0 开始)中值为 1
的偶数下标的个数。
用 odd
表示在 n
的二进制形式(下标从 0 开始)中值为 1
的奇数下标的个数。
返回整数数组 answer
,其中 answer = [even, odd]
。
解:
1.关键:
(1)利用 十进制 转 二进制 的思路 : 除2 取余 ,然后 分奇偶计数即可
2.代码:
class Solution {
public:
vector evenOddBit(int n) {
//直接利用 除2取余的 十进制数 转2进制数
int i=0; // 从低位 0 下标开始用
int cnt_odd = 0;
int cnt_even = 0;
while(n!=0)
{
int num_mod = n%2;
if(i%2 ==1 && num_mod==1)
{
cnt_odd++;
}
else if(i%2 == 0 && num_mod==1)
{
cnt_even++;
}
i++;
n=n/2;
}
return {cnt_even,cnt_odd};
}
};
T2:检查 国际象棋(马)跳“日”字的 方式 是否可以遍历整个棋盘
骑士在一张 n x n
的棋盘上巡视。在有效的巡视方案中,骑士会从棋盘的 左上角 出发,并且访问棋盘上的每个格子 恰好一次 。
给你一个 n x n
的整数矩阵 grid
,由范围 [0, n * n - 1]
内的不同整数组成,其中 grid[row][col]
表示单元格 (row, col)
是骑士访问的第 grid[row][col]
个单元格。骑士的行动是从下标 0 开始的。
如果 grid
表示了骑士的有效巡视方案,返回 true
;否则返回 false
。
注意,骑士行动时可以垂直移动两个格子且水平移动一个格子,或水平移动两个格子且垂直移动一个格子。下图展示了骑士从某个格子出发可能的八种行动路线。
解:
1.关键:
(1)有一个坑,出发点如果不在(0,0)直接返回false
(2)然后,time=1开始,利用之前大作业“贪吃蛇”的移动方向的那个2个方位数组,一个外层循环判断 移动的次数 ,内层分8个方向探索下一个位置是否 合理
2.代码:
class Solution {
public:
bool checkValidGrid(vector>& grid) {
if(grid[0][0]!=0)
{
return false;
}
// 只要 模拟 深搜 一下 即可
//利用 循环实现
int n = grid.size();
int time = 1 ;// 代表第time次访问
int x=0 , y= 0; //代表当前所处的 位置
while(time <=n*n-1)
{
int flag = 0;
//每次 可以 移动的8种可能的位置, 0<=x<=n-1 , 0<=y<=n-1
int index1[8] = {1,1,-1,-1,2,2,-2,-2};
int index2[8] = {2,-2,2,-2,1,-1,1,-1};
for(int i=0;i<=7;i++)
{
int next_x = x+index1[i];
int next_y = y+index2[i];
if(next_x >= 0 && next_x <=n-1 && next_y >=0 && next_y <=n-1)
{
//这个下标是合理 , 但是 需要 里面的val 等于 time+1
if(grid[next_x][next_y] == time)
{
time++;
x = next_x;
y = next_y;
flag = 1;
break;
}
}
}
if(flag == 0)
{
return false;
}
}
return true;
}
};
T3:美丽子集的个数:
母题:枚举出所有的子集(即列出 幂集)
法一: 设原集合的大小为n ,那么 正好对应2的n次方中bit串,其中对应bit==1说明这个位置的元素可以加入到这个子集, 所以一共有2的n次方的子集,
解:
1.关键:
(1)外层循环:枚举0 - 1< (2)内层循环 , 2的0次方 ,2的1次方。。。一直到2的n-1次方, 然后和 bit_str 按位与& 如果不为0,说明 bit_str在这个位置的 bit==1 ,原数组中的这个元素可以 加入到新的子集中 2.代码: 法二:利用递归的方式 进行 实现 解: 1.关键: (1)我没有 想到的是,0-n-1层都是 在向2个方向递归,加入 or 不加入 一个元素,但是,一直到最深层 才真正枚举完 一种子集 (2)递归的 参数:cur考虑的数组中cur位置的元素,nums原数组,全局参数:tmp临时数组,ans最终结果数组 2.代码: 回到 “周赛 ”这个题目: 给你一个由正整数组成的数组 如果 返回数组 解: 1.关键: (1)依然 借鉴 “母题”的思想, 只不过 稍微添加一些东西即可 (2)递归的第一个方向一定成立,也就是 不加入这个元素一定可以继续下一层 , 但是, 需要time[nums[i]-k] 和 time[nums[i]+k] 都为 0 才能保证 time[nums[i]]++ 可以 做到 (3)每次到达最深层的时候 cnt++ 即可: 2.代码: T4:执行任意次 操作之后的 MEX 给你一个下标从 0 开始的整数数组 在一步操作中,你可以对 数组的 MEX (minimum excluded) 是指其中数组中缺失的最小非负整数。 返回在执行上述操作 任意次 后, 解: 第一次 超时的 代码 总算知道 哪里超时了, 就是那个while循环中while(Set.count(mod_X) && mod_x<=size),这个循环时不必要的, 因为最终那个while循环可以改为: //反正 可以 利用 一个大小为 value的vector数组容器存储下所有的 mod_x出现的次数 修改后(借鉴了 某人)的代码如下: 最后,总结一下: (1)确实 没有AC,不过 思路都在形成 (2)第3题,关于 “幂集”的问题 ,“生成所有子集”这个“母题”需要 熟练掌握, 然后举一反三,“巧妇难为无米之炊” (3)第4题:一个关于 “数论”中 余数的问题:<1>关于 负数的 除法取余,操作 <2>Map有的时候 可以 直接 用一个数组替代class Solution {
public:
vector
class Solution {
public:
vector
nums
和一个 正 整数 k
。nums
的子集中,任意两个整数的绝对差均不等于 k
,则认为该子数组是一个 美丽 子集。nums
中 非空 且 美丽 的子集数目。nums
的子集定义为:可以经由 nums
删除某些元素(也可能不删除)得到的一个数组。只有在删除元素时选择的索引不同的情况下,两个子集才会被视作是不同的子集。class Solution {
public:
int cnt = 0;
//这里不适用 set,而是使用一个数组进行记录
int time[4001]={0};
int beautifulSubsets(vector
nums
和一个整数 value
。nums
中的任一元素加上或减去 value
。
nums = [1,2,3]
且 value = 2
,你可以选择 nums[0]
减去 value
,得到 nums = [-1,2,3]
。
[-1,2,3]
的 MEX 是 0
,而 [1,0,3]
的 MEX 是 2
。nums
的最大 MEX 。class Solution {
public:
int findSmallestInteger(vector
class Solution {
public:
int findSmallestInteger(vector