- 错误的集合
最开始的想法是排序。但是
class Solution {
public:
vector<int> findErrorNums(vector<int>& nums) {
vector<int> count(nums.size());
for(int& x:nums)
{
count[x-1]++;
}
int lose = -1;
int repeat = -1;
for(int i=0;i<count.size();i++)
{
if(count[i]==0)
lose=i+1;
if(count[i]==2)
repeat=i+1;
}
return {repeat, lose};
}
};
- 寻找重复数
思路一:异或运算。先从1异或到n,将得到的值与数组中的每个值异或运算。结果不对,因为,数组中并非每个数都会出现一遍。
思路二:用数组代替hashtable。
public:
int findDuplicate(vector<int>& nums) {
vector<int> v(nums.size()-1);
for(int& x:nums)
{
if(v[x-1]==1)
return x;
v[x-1]++;
}
return 0;
}
};
思路三:弗洛伊德环
3. 数组的度
用一个hashtabel记录没个数字出现的位置。
class Solution {
public:
int findShortestSubArray(vector<int>& nums) {
unordered_map<int, vector<int>> m;
for(int i=0;i<nums.size();i++)
{
vector<int> v;
m[nums[i]] = v;
}
for(int i=0;i<nums.size();i++)
{
m[nums[i]].push_back(i);
}
int maxFre = 0;
int ans = nums.size();
for(pair<int, vector<int>>x:m) //为何不能写成for(pair<int, vector<int>>&x:m)
{
if(x.second.size()==maxFre)
{
ans = min(x.second[x.second.size()-1] - x.second[0] + 1,ans);
}
else if(x.second.size()>maxFre)
{
maxFre = x.second.size();
ans = x.second[x.second.size()-1] - x.second[0] + 1;
}
}
return ans;
}
};
答案用hashtable记录没个数字出现的次数,以及第一次出现和最后一次出现的位置。
4. 托普利兹矩阵
先判断左下角,再判断右边部分
class Solution {
public:
bool isToeplitzMatrix(vector<vector<int>>& matrix) {
if(matrix.size()==0)
return false;
int rows=matrix.size();
int cols=matrix[0].size();
for(int i=rows-1;i>0;i--)
{
int val = matrix[i][0];
int r=i,c=0;
while(r<rows && c<cols)
{
if(matrix[r][c] != val)
return false;
r++;
c++;
}
}
for(int i=0;i<cols;i++)
{
int val = matrix[0][i];
int r=0,c=i;
while(r<rows && c<cols)
{
if(matrix[r][c] != val)
return false;
r++;
c++;
}
}
return true;
}
};
评论区解法:判断上一行去掉最后一个元素和下一行去掉第一个元素后是否相等。
- 嵌套数组
我的方法:暴力法。超时。利用set判断是否有重复。
class Solution {
public:
int arrayNesting(vector<int>& nums) {
int maxLen = 0;
for(int i=0;i<nums.size();i++)
{
unordered_set<int> s;
int curLen;
int curVal = nums[i];
int curIndex = i;
do{
curLen = s.size();
s.insert(nums[curIndex]);
curIndex = nums[curIndex];
}while(s.size()>curLen); //do while ,新学的
maxLen = max(maxLen, curLen);
}
return maxLen;
}
};
其实不需要用集合来判断,因为对于第i轮循环,最终肯定会等于 i。
另外,如果某个元素之前已经被访问过,那么这轮循环得到的值肯定不是最大值,可以直接跳过。所以就有如下答案的解答。
class Solution {
public:
int arrayNesting(vector<int>& nums) {
int maxLen = 0;
vector<bool> visited(nums.size(), false);
for(int i=0;i<nums.size();i++)
{
//cout << "a" << endl;
//cout << visited[0] << endl;
//cout << visited[i] << endl;
if(!visited[i])
{
int curLen=0;
int curIndex = i;
do{
curLen++;
visited[curIndex] = true;
curIndex = nums[curIndex];
}while(curIndex != i);
maxLen = max(maxLen, curLen);
}
}
return maxLen;
}
};
另外,答案还提到,可以用O(1)的空间复杂度来做。但是需要改变原始数组。也就是,㘝访问过,就把原始数组的对应位置改为-1.
- 最多能完成排序的块
当我们需要检查 [0, 1, …, n-1] 中前 k+1 个元素是不是 [0, 1, …, k] 的时候,只需要检查其中最大的数是不是 k 就可以了。
class Solution {
public:
int maxChunksToSorted(vector<int>& arr) { //08:06 - 08:26
int maxNum = 0, count = 0, ans=0;
for(int i=0; i<arr.size();i++)
{
maxNum = max(arr[i], maxNum);
count++;
if(count==maxNum+1)
ans++;
}
return ans;
}
};