1. 只出现一次的数字 136
2020/08/09
136是题号。以后就不重复了。
一开始的想法是两个指针走两遍,复杂度是o(n^2)。i从头往后走,在每个位置都先假设flag=0,然后让 j 遍历vector一次。当且仅当i!=j && nums[i]=nums[j];时,flag=1.。然后在i的循环里面判断,如果flag==0,就返回nums[i]。
然而超时了。
leetcode的官方解法是利用位运算。
class Solution {
public:
int singleNumber(vector<int>& nums) {
int ret = 0;
for (auto e: nums) ret ^= e;
return ret;
}
};
上述代码中
for (auto x : nums)
作用就是迭代容器中所有的元素,每一个元素的临时名字就是x,等同于下边代码
for (vector<int>::iterator iter = nums.begin(); iter != nums.end(); iter++)
后面的ret ^=e;可以写为ret ^= *iter;
2. 存在重复元素 217
题目:给定一个整数数组,判断是否存在重复元素。
如果任意一值在数组中出现至少两次,函数返回 true 。如果数组中每个元素都不相同,则返回 false 。
破事:本来两个指针循环解决问题,对于每一个i,都有j指针来让ij对应的元素相比较,看是否相等。运行通过了,但是提交超时了。
但是下面这个不超时。
class Solution {
public:
bool containsDuplicate(vector<int>& nums) {
sort(nums.begin(),nums.end());
for(int i=1;i<nums.size();i++)
{
if(nums[i]==nums[i-1])
return true;
}
return false;
}
};
/作者:zrita
链接:https://leetcode-cn.com/problems/contains-duplicate/solution/c-sortmapsetsan-chong-fang-fa-jian-ji-yi-dong-z-by/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。/
3. 350. 两个数组的交集 II
给定两个数组,编写一个函数来计算它们的交集。
/示例 1:
输入: nums1 = [1,2,2,1], nums2 = [2,2]
输出: [2,2]
说明:
输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。 我们可以不考虑输出结果的顺序。/
这题的做法1是哈希映射,我得学学数据结构或者郭炜的算法了。
做法2是排序。
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
sort(begin(nums1), end(nums1));
sort(begin(nums2), end(nums2));
int i = 0, j = 0, k = 0;
while (i < nums1.size() && j < nums2.size()) {
if (nums1[i] < nums2[j]) {
++i;
} else if (nums1[i] > nums2[j]) {
++j;
} else {
nums1[k++] = nums1[i++];
++j;
}
}
return vector<int>(begin(nums1), begin(nums1) + k);
}
//return vector<int>(nums1.begin(),nums1.begin()+k);也是可以的
/*作者:LeetCode
链接:https://leetcode-cn.com/problems/intersection-of-two-arrays-ii/solution/liang-ge-shu-zu-de-jiao-ji-ii-by-leetcode/
*/
4.189. 旋转数组
试了试4种方法。在new数组上面莫名卡了。
5.36.有效的数独
犯了一个奇妙的错误。col[j][curNumber]写成了col[i][curNumber]
废了一些不该废的时间。
*
6. 48. 旋转图像
把一个n*n矩阵顺时针反转90°
观察旋转的特点,相对于图案,相当于第i行第j列的元素,变成第j行第n-i列的元素。那么我们就可以通过i和j的对称交换,使第i行第j列的元素和第j行第i列的元素进行交换,然后通过对第j列元素的排序,就可以让第j列变为第n-j列。在这个转化的过程中,原先第j行第i列的元素会先移动到第i行第j列,然后转移到第i行第n-j列,同样符合旋转过程中行列变化的规律。
class Solution {
public:
void rotate(vector<vector<int>>& matrix) {
int len=matrix.size(),high,low;
for(int i=0;i<len;i++)
for(int j=i;j<len;j++) swap( matrix[i][j],matrix[j][i]);
for(int i=0;i<len;i++)
{
low=0;high=len-1;
while(low<high) swap( matrix[i][low++],matrix[i][high--]);
}
}
};
作者:yan-long-xue-donglin
链接:https://leetcode-cn.com/problems/rotate-image/solution/xuan-zhuan-shuang-bai-by-yan-long-xue-donglin/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
他的版本是我的简化版。
我的版本比较暴力。
class Solution {
public:
void rotate(vector<vector<int>>& matrix) {
int size = matrix.size();
int n=size;
int i,j;
int a=size/2;
for(i=0;i<a;i++){
for(j=i;j<size-i-1;j++){
int temp1,temp2;
temp1 = matrix[j][n-1-i];
matrix[j][n-1-i]=matrix[i][j];
temp2=matrix[n-1-i][n-1-j];
matrix[n-1-i][n-1-j]=temp1;
matrix[i][j]=matrix[n-1-j][i];
matrix[n-1-j][i]=temp2;
}
}
}
};
重点还是那句话,“相当于第i行第j列的元素,变成第j行第n-i列的元素。”也就是说,(i,j) >(j,n-1-i) >(n-1-i,n-1-j) >(n-1-j,i)。
说实话,如果自己不想明白这个题目的做法,恐怕光看代码是看不懂我在写什么的。
另外我又喜闻乐见的犯了把最后一个j写成i的错误。
我觉得这些代码,自己做过一遍后,第二遍应该看懂别人的想法。
7.26.删除排序数组中的重复项
算法比较简单,但是我犯了三个小错误
1 忘了return
2 把“==”写成了“=”
3 没想到还要考虑容器为空的情况(容器为空的话,我写的指针会直接指在容器外)
//刚停了个电,之前没保存,不得已把这些又写了一遍
8.122.买卖股票的最佳时机 II
class Solution {
public:
int maxProfit(vector<int>& prices) {
int maxPro=0,tmp=0;
for(int i = 1;i<prices.size();i++){
tmp=prices[i]-prices[i-1];
if (tmp>0)
maxPro+=tmp;
}
return maxPro;
}
};
传说中的贪心算法,也就是官方的解法3.说实话本题解法中,暴力解法最难写,贪心算法最好写但是想不明白为啥贪心算法能用。