class Solution {
public:
int singleNumber(vector<int>& nums) {
//根据:某个元素只出现一次 直接来异或
int ret=0;
for(auto e:nums)
{
ret=ret^e;
}
return ret;
}
};
nums
中的所有元素,并进行异或运算,最终得到的结果就是只出现一次的元素。
class Solution {
public:
vector<vector<int>> generate(int numRows) {
vector<vector<int>> vv;
vv.resize(numRows);//先给好numRows个元素,即vv里能存vector<int>
for(int i=0;i<numRows;i++)//对一行进行处理
{
vv[i].resize(i+1);//每一行里再开好对应的大小
vv[i].front()=vv[i].back()=1;//最左最右都是1
}
for(int i=2;i<numRows;i++)
{
for(int j=1;j<i;j++)
{
vv[i][j]=vv[i-1][j-1]+vv[i-1][j];
}
}
return vv;
}
};
vv
,用于存储杨辉三角的数据。vv
的第i行第j列的元素表示杨辉三角中第i行第j列的数值。
vv.resize(numRows)
为vv
分配了numRows
个元素,即vv
中可以存储numRows
行的vector(即numRows个vector)
vv[i].resize(i+1)
为其分配了合适的大小,即第i行有i+1个元素。(从0开始)
vv[i][j] = vv[i-1][j-1] + vv[i-1][j]
。
通过以上步骤,最终得到了杨辉三角的前numRows
行。
举个例子:
如果numRows
为5,那么vv
的内容将会是:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
class Solution {
public:
vector<vector<int>> generate(int numRows) {
vector<vector<int>> vv;
vv.resize(numRows);//先给好numRows个元素,即vv里能存vector<int>
for(int i=0;i<numRows;i++)//对一行进行处理
{
vv[i].resize(i+1,0);//每一行里再开好对应的大小
vv[i].front()=vv[i].back()=1;//最左最右都是1
}
for(int i=0;i<numRows;i++)
{
for(int j=0;j<vv[i].size();j++)
{
if(vv[i][j]==0)
vv[i][j]=vv[i-1][j-1]+vv[i-1][j];
}
}
return vv;
}
};
大致都一样,不过在进行相加这里头和尾也都算上,因为在一开始开空间,全都给0了。 能多加一个条件判断,不怕越界
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
if(nums.size()==0)//处理0的情况
{
return 0;
}
int index=1;
int pre_index=0;
while(index<nums.size())//如果就一个元素,根本不会进来
{
if(nums[index]!=nums[pre_index])
{
nums[pre_index+1]=nums[index];//赋值给下一个后加一,就是新位置了,再用后面的来比
pre_index++;
}
index++;
}
return pre_index+1;//下标加1才是元素个数
}
};
这里需要注意,给出的数组是总体上是升序的
index
和 pre_index
,分别代表当前遍历的元素和上一个不重复元素的位置。index
初始值为1,因为我们从第二个元素开始遍历;pre_index
初始值为0,因为第一个元素肯定是不重复的
pre_index
更新为当前的位置(新的不重复元素的位置)
int MoreThanHalfNum_Solution(vector<int>& numbers) {
// write code here
int half=numbers.size()/2;
for(int i=0;i<numbers.size();i++)
{
int count=0;
for(int j=i+1;j<numbers.size();j++)
{
if(numbers[i]==numbers[j])
{
count++;
}
if(count>=half)
{
return numbers[i];
}
}
}
return numbers[0];
}
};
暴力运用两次循环,对每个元素进行统计,大家都知道效率肯定很差。 下面看第二个
int MoreThanHalfNum_Solution(vector<int>& numbers) {
// write code here
int count = 0;
int candidate=numbers[0];//一开始就假设第一个是候选者
for (auto num : numbers) {
if (count == 0) {
candidate = num;
}
count += (num == candidate) ? 1 : -1;//相等就+1,不等-1
}
return candidate;
}
};
摩尔投票法的核心思想是抵消。在遍历数组时,我们维护一个候选元素和一个计数器。遍历过程中,如果计数器为0,就将当前元素设为候选元素;如果遇到与候选元素相同的元素,则计数器加1,否则计数器减1。这样做的原因是,如果某个元素出现的次数超过数组长度的一半,那么它与其他元素出现次数的抵消会导致最终留下的候选元素就是出现次数超过一半的元素。
让我们通过一个例子来说明这个过程:
假设数组为:[3, 3, 4, 2, 4, 4, 2, 4, 4]。
我们用变量candidate来存储候选元素,用变量count来存储候选元素的计数器。
最终留下的候选元素是4,它出现的次数超过了数组长度的一半。
这就是摩尔投票法的原理:通过抵消的过程,最终留下的候选元素就是出现次数超过一半的元素。
今天就到这里啦!