目录
- 1. 只出现一次的数
- 2. 杨辉三角
- 3. 删除有序数组中的重复项
- 4. 只出现一次的数II
- 5. 只出现一次的数III
- 6. 数组中出现次数超过一半的数
- 7. 电话号码的字母组合(多叉树遍历)
1. 只出现一次的数
- 题目信息:
- 题目链接:
只出现一次的数- 思路:位运算规律,a ^ a = 0,0 ^ a = a
class Solution
{
public:
int singleNumber(vector<int>& nums)
{
int num = 0;
for(auto e : nums)
{
num ^= e;
}
return num;
}
};
2. 杨辉三角
- 题目信息:
- 题目链接:
杨辉三角- 思路:将vector初始化为0,然后再将首尾处理为1,当num[i][j]为0时,nums[i][j] = nums[i - 1][j] + nums[i - 1][j - 1]
class Solution
{
public:
vector<vector<int>> generate(int numRows)
{
vector<vector<int>> vv;
vector<int> v1(1, 1);
vv.push_back(v1);
if (numRows == 1)
{
return vv;
}
v1.push_back(1);
vv.push_back(v1);
if (numRows == 2)
{
return vv;
}
vector<int> v2(v1);
for (int i = 1; i < numRows - 1; i++)
{
v2.push_back(1);
for (int j = 1; j < v2.size() - 1; j++)
{
v2[j] = vv[i][j - 1] + vv[i][j];
}
vv.push_back(v2);
v1 = v2;
}
return vv;
}
};
优化:
class Solution
{
public:
vector<vector<int>> generate(int numRows)
{
vector<vector<int>> ret;
for(int i = 0; i < numRows; i++)
{
ret.push_back(vector<int>(i + 1));
ret[i].front() = ret[i].back() = 1;
}
for(int i = 0; i < numRows; i++)
{
for(int j = 0; j < ret[i].size(); j++)
{
if(ret[i][j] == 0)
{
ret[i][j] = ret[i - 1][j] + ret[i - 1][j - 1];
}
}
}
return ret;
}
};
3. 删除有序数组中的重复项
- 题目信息:
- 题目链接:
删除有序数组中的重复项- 思路:
<1> 挪移覆盖法O(n^2)
<2> 双指针法(快排),前提条件:有序
class Solution
{
public:
int removeDuplicates(vector<int>& nums)
{
//双指针法
int cur = 1;
int pre = 0;
while(cur < nums.size())
{
if(nums[pre] != nums[cur])
{
pre++;
nums[pre] = nums[cur];
}
cur++;
}
return pre + 1;
}
};
4. 只出现一次的数II
- 题目信息:
- 题目链接:
只出现一次的数II- 思路:遍历计数法
class Solution
{
public:
int singleNumber(vector<int>& nums)
{
sort(nums.begin(), nums.end());
int count = 1;
int i = 0;
for(i = 0; i + 1 < nums.size(); i++)
{
if(nums[i] == nums[i + 1])
{
count++;
}
else
{
if(count != 3)
{
break;
}
count = 1;
}
}
return nums[i];
}
};
5. 只出现一次的数III
- 题目信息:
- 题目链接:
只出现一次的数III- 思路:排序 + 遍历计数
class Solution
{
public:
vector<int> singleNumber(vector<int>& nums)
{
vector<int> v;
sort(nums.begin(), nums.end());
int count = 1;
for(int i = 1; i < nums.size(); i++)
{
if(nums[i - 1] == nums[i])
{
count++;
}
else
{
if(count == 1)
{
v.push_back(nums[i - 1]);
}
if(i == nums.size() - 1 && nums[i - 1] != nums[i])
{
v.push_back(nums[i]);
}
count = 1;
}
}
return v;
}
};
6. 数组中出现次数超过一半的数
- 题目信息:
- 题目链接:
数组中出现次数超过一半的数- 思路:排序 + 计数遍历
class Solution
{
public:
int MoreThanHalfNum_Solution(vector<int>& numbers)
{
sort(numbers.begin(), numbers.end());
int num = numbers[0];
int count = 1;
for(int i = 0; i + 1 < numbers.size(); i++)
{
if(count > numbers.size() / 2)
{
break;
}
if(numbers[i] != numbers[i + 1])
{
num = numbers[i + 1];
count = 1;
}
else
{
count++;
}
}
return num;
}
};
7. 电话号码的字母组合(多叉树遍历)
- 题目信息:
- 题目链接:
电话号码的字母组合- 思路:多叉树遍历,递归:递归子函数的参数(递归需要的参数),递归的结束条件
class Solution
{
public:
string data[10] = { "","","abc", "def","ghi","jkl","mno","pqrs","tuv","wxyz" };
//先层数+1,再插入
//count第几层
void combine(vector<string>& ret, string& digits, int count, const string& ans)
{
//返回条件控制,什么时候返回
if (count == digits.size())
{
ret.push_back(ans);
return;
}
//多叉树遍历操作
//pos第几个
for (int pos = 0; pos < data[digits[count] - '0'].size(); pos++)
{
//字符串拼接,不更改原本的值,多次使用
combine(ret, digits, count + 1, ans + data[digits[count] - '0'][pos]);
}
}
vector<string> letterCombinations(string digits)
{
vector<string> ret;
//特殊处理
if (digits.size() == 0)
{
return ret;
}
//层数,当层的哪个字符
//第几个答案,组成结果多次使用不可更改原值
string ans;
int count = 0;
combine(ret, digits, count, ans);
return ret;
}
};