只出现过一次的数字(简单)
这道题使用异或就非常简单了,所有数异或到一起,相同的数据双双消除,只剩下一个的数。
class Solution {
public:
int singleNumber(vector<int>& nums) {
int val = 0;
for(auto e : nums)
{
val ^= e;
}
return val;
}
};
变形题:(简单)
137. 只出现一次的数字 II - 力扣(LeetCode)
思路:统计出32个位中,每个位合计起来1出现的次数。
每个位1的个数要么是3n,要么是3n+1。而 3n+1 的位就是只出现一次的数的位
class Solution {
public:
int singleNumber(vector<int>& nums) {
// 统计32个位合计1的个数
int bitArray[32] = {0};
for(auto e : nums)
{
for(size_t i = 0; i < 32; ++i)
{
if(e & (1 << i))
{
bitArray[i]++;
}
}
}
int num = 0;
// 找出3n+1的位,这些位就是只出现1次的数为1的位
for(size_t i = 0; i<32; ++i)
{
// 将3n+1的位或成1
if(bitArray[i] % 3 == 1)
{
num |= (1 << i);
}
}
return num;
}
};
变形题:(中等)
260. 只出现一次的数字 III - 力扣(LeetCode)
class Solution {
public:
vector<int> singleNumber(vector<int>& nums) {
// 异或完成后,val就是只出现一次的两个数据异或的结果
int val = 0;
for(auto e : nums)
{
val ^= e;
}
/* 解题思路 */
// 此时的val就是两个我们要找的数据异或的结果,val中为1的位就是两个数不同的位
// 即这个位有一个数为0有一个数为1
// 此时我们将所有数据分为两组,一组是这个位为0的数,一组是这个位为1的数
// 此时两个只出现过一次的数会被分到两个组中
// 而其他的出现过两次的数也会被分过去,此时的问题就变成了问题1:
// 一个整数数组中有1个只出现过1次的数,其他数都出现两次,找出这个只出现1次的数
// 此时再按照问题1处理两组数据
// 将一组中所有的数异或到一起,此时的异或结果就是这组数据中只出现过一次的数据。
/* end */
// 找到val中为1的位,并以此为依据将原数组分成两组数组
size_t i = 0;
for(; i <32 ; ++i)
{
if(val & (1 << i))
break;
}
// 将第i位为0和为1的分开成两组进行异或,得到的num1和num2就是两个只出现过一次的数
int num1 = 0, num2 = 0;
for(auto e : nums)
{
if(e & (1 << i))
num1 ^= e;
else
num2 ^= e;
}
vector<int> v;
v.push_back(num1);
v.push_back(num2);
return v;
}
};
杨辉三角(简单)
class Solution {
public:
vector<vector<int>> generate(int numRows) {
vector<vector<int>> vv;
vv.resize(numRows);
// 构建初始的杨辉三角,每行开头和结尾赋值为1
for(size_t i = 0;i<numRows;++i)
{
vv[i].resize(i+1);
vv[i][0] = 1;
vv[i][vv[i].size() - 1] = 1;
}
// 填充杨辉三角
for(size_t i = 0;i<vv.size();++i)
{
for(size_t j = 0;j<vv[i].size();++j)
{
// 不为1的需要被填充
if(vv[i][j] != 1)
{
vv[i][j] = vv[i-1][j-1] + vv[i-1][j];
}
}
}
return vv;
}
};