1.左移(<<)一位相当于乘2,右移(>>)一位相当于除2(不完全等同),
2.格林编码
/*当 n == 1 ,返回 [0,1] .
当 n == 2 ,返回 [0,1,3,2] .
当 n == 3 ,返回 [0,1,3,2,6,7,5,4] .
当 n == …… ,返回 [0,1,3,2,6,7,5,4,……] .
可见当 n == k,就是在 n == k - 1 的情况下增加了一些数字。并且根据题意知道,n每增加1,整数的范围会扩大一倍。(也可以观察结果得到)*/
//格雷编码的生成过程, G(i) = i ^ (i/2);
推导:
如 n = 3:
G(0) = 000,
G(1) = 1 ^ 0 = 001 ^ 000 = 001
G(2) = 2 ^ 1 = 010 ^ 001 = 011
G(3) = 3 ^ 1 = 011 ^ 001 = 010
G(4) = 4 ^ 2 = 100 ^ 010 = 110
G(5) = 5 ^ 2 = 101 ^ 010 = 111
G(6) = 6 ^ 3 = 110 ^ 011 = 101
G(7) = 7 ^ 3 = 111 ^ 011 = 100
3.两种求子集
1)题目:给你一个整数数组 nums ,其中包含重复元素,请你返回该数组所有可能的子集(幂集)。
解集 不能 包含重复的子集。返回的解集中,子集可以按 任意顺序 排列。
vector<vector<int>> subsetsWithDup(vector<int>& nums)
{
DFS(nums,0);
return res;
}
vector<vector<int>>res;//结果
vector<int> cur;//当前结果
void DFS(vector<int>&num,int startindex)
{
res.push_back(cur);//子集中有一个空集
for(int i=startindex;i<num.size();i++)//需要去重的话勇for循环
{
if(i!=startindex&&num[i]==num[i-1]) continue;
cur.push_back(num[i]);
DFS(num,i+1);
cur.pop_back();
}
}
2) 已知一组数(无重复元素),求这组数可以组成的所有子集,结果中不可有无重复的子集 例如:nums[]={1,2,3} 结果为:[[],[1],[1,2],[1,2,3],[1,3],[2],[2,3],[3]] 思路:每一个数字有可选择和不选择两种情况 如果选择了1,递归的选择2
void fn(int i, vector<int>& num, vector<int>& temp, vector<vector<int>>& ret)
{
if (i >= num.size())
return;
temp.push_back(num[i]);
ret.push_back(temp);//存起来倒最终结果
fn(i + 1, num, temp, ret);
temp.pop_back();//回溯时,把最后放的数据拿出来
fn(i + 1, num, temp, ret);//继续递归的向下走
//不选择数还是选择数都要往后递归,比如pop出了2 还是要递归的选择2之后的数
}
void main()
{
vector<int> num;
num.push_back(1);
num.push_back(2);
num.push_back(3);
num.push_back(4);
vector<int> temp;
vector<vector<int>>ret;
fn(0, num, temp, ret);
for (int i = 0; i < ret.size(); i++)
{
for (int j = 0; j < ret[i].size(); j++)
{
cout << ret[i][j] << " ";
}
cout << endl;
}
}
4.当遇到有关26个英文字母问题时,恰巧需要取余运算时,可以将字母按0-25对应英文A到Z,这样数字对26取余就可以得到对应某个字母的数字
为什么不用1-26呢?
因为26%26=0,但是实际的对应字母应该是z
5.substr()函数
是C++语言函数,主要功能是复制子字符串,要求从指定位置开始,并具有指定的长度。如果没有指定长度Count或Count+_Off超出了源字符串的长度,则子字符串将延续到源字符串的结尾。——摘自百科词条
语法 substr(size_type _Off = 0,size_type _Count = npos) 一种构造string的方法 形式 : s.substr(pos, len) 返回值: string,包含s中从pos开始的len个字符的拷贝(pos的默认值是0,len的默认值是s.size() - pos,即不加参数会默认拷贝整个s) 异常 :若pos的值超过了string的大小,则substr函数会抛出一个out_of_range异常;若pos+n的值超过了string的大小,则substr会调整n的值,只拷贝到string的末尾
6.isalpha():判断字符是不是字母的函数
isplnum():判断字符是不是字母或者数字的函数
tolower();把大写字母转小写字母的函数,也是单个字符转
toupper();把小写字母转大写,单个字符
参数和返回值见如下代码
bool isPalindrome(string s)
{
string str;//只保留
if(s==" ")return true;
for (int i = 0; i < s.size(); i++)
{
if (isalnum(s[i]))//验证是不是字母或者数字的函数
{
str +=tolower(s[i]);//把大写转小写
}
}
for (int i = 0, j = str.size() - 1; i < j; i++, j--)
{
if (str[i] != str[j])
{
return false;
}
}
return true;
}
void main()
{
string s = "A man, a plan, a canal: Panama";
cout << isPalindrome(s) << endl;
}
7.vector<string>类型的返回值,往它里面push_back的方法
定义一个string类型变量s,把要放入的一个单独的部分用to_string函数转换,s可以进行+操作,这样描述可能有点难懂,下面有一个示例
给定一个 无重复元素 的 有序 整数数组 nums 。返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表 。也就是说,nums 的每个元素都恰好被某个区间范围所覆盖,并且不存在属于某个范围但不属于 nums 的数字 x 。
vector<string> summaryRanges(vector<int>& nums)
{
vector<string> res;
int n = nums.size();
int left = 0, right = left + 1;
while(left<n)
{
string s="";
while(right<n&&nums[right]==nums[right-1]+1)
{
right++;
}
if(left<right-1)//这里比较的是right-1 是因为上一个while循环中是比较后对right进行了++的
{
s+=to_string(nums[left]);
s+="->";
s+=to_string(nums[right-1]);
}
else if(left==right-1)
{
s+=to_string(nums[left]);
}
res.push_back(s);
left=right;
right++;
}
return res;
}
输入输出示例:
输入:nums = [0,1,2,4,5,7] 输出:["0->2","4->5","7"] 解释:区间范围是: [0,2] --> "0->2" [4,5] --> "4->5" [7,7] --> "7"文章来源:https://www.toymoban.com/news/detail-433634.html
解释:题中要求分割空间,需要把一段一段string类型的数据push_back进入res中,所以我们定义了s,把一段需要插入的数据放好之后,直接把s push_back进去就行。文章来源地址https://www.toymoban.com/news/detail-433634.html
到了这里,关于过去一周的刷题笔记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!