数组/字符串
给你一个 非严格递增排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。
【26】删除有序数组中的重复项
方法一:申请额外空间
时间o(n),空间o(1)
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int left = 0;
int right = 0;
set<int> tmp_set;
vector<int> tmp;
for(int i =0;i<nums.size();i++){
if(tmp_set.find(nums[i]) == tmp_set.end())
{
tmp_set.insert(nums[i]);
tmp.push_back(nums[i]);
}
}
for(int i =0;i<tmp.size();i++){
nums[i] = tmp[i];
}
return tmp.size();
}
};
双指针,原地修改:
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int n = nums.size();
if(0 == n){
return 0;
}
int fast = 1,slow = 1;
while(fast<n){
if(nums[fast] != nums[fast-1]){
nums[slow] = nums[fast];
slow++;
}
fast++;
}
return slow;
}
};
【80】删除有序数组中的重复项II
给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
class Solution {
public:
//原地修改数组只能用快慢数组进行覆盖
//并且数组是有序的,所以只用考虑两个之间是否是相同的
int removeDuplicates(vector<int>& nums) {
int res =0;
int n = nums.size();
if(n <= 2) return n;
int slow = 2,fast =2;//slow指针,改造后的数组长度
while(fast<n){
if(nums[slow -2] != nums[fast]){
nums[slow] = nums[fast];
slow++;
}
fast++;
}
return slow;
}
};
【88】合并两个有序数组
给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m 个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。
从数组尾部开始算tail指针,然后一个nums1 和 ptr1 和 nums2 的ptr2的指针分别移动。
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
//不用额外的空间 O(1) 从后做指针
//时间复杂度 O(M+N)
int p1 = m-1,p2 = n -1;//两个数组的
int tail = m+n-1;//从后遍历的指针
int cur;
while (p1>=0 || p2>=0){
if(p1 == -1){//p1已经遍历完了
cur = nums2[p2--];
}else if(p2 == -1){//p2已经遍历完了
cur = nums1[p1--];
}else if(nums1[p1] > nums2[p2]){//把nums1复制进去
cur = nums1[p1--];
}else{
cur = nums2[p2--];
}
nums1[tail--] = cur;
}
}
};
双指针
【15】三数之和
(部分用例,超出时间限制…)
class Solution {
public:
int compare_vec(vector<int>& nums1,vector<vector<int>>& nums2){
for(int i = nums2.size()-1;i>=0;i--){//一个向量一个向量比
if(nums1[0] == nums2[i][0]){
if(nums1[1] == nums2[i][1] && nums1[2] == nums2[i][2] ){
return 1;
}
}else{
return 0;
}
}
return 0;
}
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> res;
int n = nums.size();
if( 0 ==n )return res;
int count = 0;
//排序
sort(nums.begin(),nums.end());
//确定三元组
for(int i =0;i<n;i++){
for(int j = i+1;j<n;j++){
for(int k = j+1;k<n;k++){
if(nums[i]+nums[j]+nums[k] == 0)
{
vector<int> tmp = vector<int>{nums[i],nums[j],nums[k]};
if(count != 0 && compare_vec(tmp,res)){
continue;
}
res.push_back(vector<int>{nums[i],nums[j],nums[k]});
count++;
}
}
}
}
return res;
}
};
双指针:
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> res;//定义返回数组
sort(nums.begin(),nums.end());//对数组进行排序
for(int i =0;i<nums.size();i++){//遍历已经排序好的数组
if(nums[i]>0){//i遍历到>0的数,那么后面相加肯定大于0
return res;//返回res
}
// 去重a
if(i>0 && nums[i] == nums[i-1]){
continue;
}
int right = nums.size()-1;
int left = i+1;
while(right>left){
if(nums[i]+nums[left]+nums[right] >0 ){
right--;
}
else if(nums[i]+nums[left]+nums[right] <0){
left++;
}
else{// =0的情况
res.push_back(vector<int>{nums[i],nums[left],nums[right]});
//去重bc
while (right > left && nums[right] == nums[right - 1]) right--;
while (right > left && nums[left] == nums[left + 1]) left++;
left++;//为下一次while做准备
right--;
}
}
}
return res;
}
};
滑动窗口
矩阵
矩阵注意下标的选取,映射。
class Solution {
public:
bool isValidSudoku(vector<vector<char>>& board) {
// 行集合
unordered_set<char> row_set[9];
// 列集合
unordered_set<char> col_set[9];
// 3x3宫格集合
unordered_set<char> box_set[9];
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
char num = board[i][j];
//跳过空格
if (num != '.') {
// 检查行
if (row_set[i].find(num) != row_set[i].end()) return false;
row_set[i].insert(num);
// 检查列
if (col_set[j].find(num) != col_set[j].end()) return false;
col_set[j].insert(num);
// 检查3x3宫格
int boxIndex = (i / 3) * 3 + j / 3;//注意这个映射
if (box_set[boxIndex].find(num) != box_set[boxIndex].end()) return false;
box_set[boxIndex].insert(num);
}
}
}
return true;
}
};