LeetCode刷题总结 -- 数组篇

因为去学别的东西,也就两个月没刷题,结果该忘记的不该忘记的都忘记了。
思来想去,还是做个总结要来的好些。
不涉及那些奇思妙想的题目,就纪录最基本的东西。

文章目录

      • 1、引用传参
      • 2、快慢指针
      • 3、map、set的使用
      • 4、其余
      • 5、了解vector

1、引用传参

先来看个题目:
等下也是用这个题目

给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

示例 1:

给定数组 nums = [1,1,2], 
函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。 
你不需要考虑数组中超出新长度后面的元素。
示例 2:

给定 nums = [0,0,1,1,1,2,2,3,3,4],
函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。
你不需要考虑数组中超出新长度后面的元素。

说明:
为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:

// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝
int len = removeDuplicates(nums);

// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。
for (int i = 0; i < len; i++) {
    print(nums[i]);
}

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

以前只知道指针有这种骚操作,现在知道引用也有这种骚操作了。

2、快慢指针

对于上面这题的题解,便可以采用快慢指针的办法。
LeetCode刷题总结 -- 数组篇_第1张图片

不用快慢指针也可以,不过本文不是为了说谁的办法优秀,这题也不能体现出快慢指针的多少优越性,但是重要的是学到这个思路不是吗。

可以考虑一下下面这道题:

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。

注意:答案中不可以包含重复的三元组。
示例:
给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:

[
  [-1, 0, 1],
  [-1, -1, 2]
]

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/3sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

3、map、set的使用

以下是一个使用set的示例:
给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0。请使用原地算法。

示例 1:
输入:

[
  [1,1,1],
  [1,0,1],
  [1,1,1]
]

输出:

[
  [1,0,1],
  [0,0,0],
  [1,0,1]
]

示例 2:

输入:

[
  [0,1,2,0],
  [3,4,5,2],
  [1,3,1,5]
]

输出:

[
  [0,0,0,0],
  [0,4,5,0],
  [0,3,1,0]
]

进阶:

一个直接的解决方案是使用 O(mn) 的额外空间,但这并不是一个好的解决方案。
一个简单的改进方案是使用 O(m + n) 的额外空间,但这仍然不是最好的解决方案。
你能想出一个常数空间的解决方案吗?

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/set-matrix-zeroes
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

我的解法:

void setZeroes(vector<vector<int>>& matrix) {
    if(matrix.empty())
        return;
    int r = matrix.size();
    int c = matrix[0].size();

    set<int> rs;
    set<int> cs;
    set<int>::iterator sit;

    //将有0的行列提取出来
    for (int i = 0; i < r; i++)
    {
        for (int j = 0; j < c; j++)
        {
            if (matrix[i][j] == 0)
            {
                rs.insert(j);
                cs.insert(i);
            }
        }
    }

    if (!cs.empty())
    {
        int a = c;
        vector<int> temp;
        while (a > 0)
        {
            temp.push_back(0);
            a--;
        }
        
        //将行清零
        for (sit = cs.begin(); sit != cs.end(); sit++)
        {
            matrix[*sit] = temp;
        }
    }

    //将列清零
    if (!rs.empty())
    {
        for (sit = rs.begin(); sit != rs.end(); sit++)
        {
            for (int k = 0; k< r; k++)
            {
                matrix[k][*sit] = 0;
            }
        }
    }
}

思路:
LeetCode刷题总结 -- 数组篇_第2张图片
接下来是一个map的使用示例:

给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。
示例:

输入: ["eat", "tea", "tan", "ate", "nat", "bat"]
输出:
[
  ["ate","eat","tea"],
  ["nat","tan"],
  ["bat"]
]

说明:
所有输入均为小写字母。
不考虑答案输出的顺序。

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/group-anagrams
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

我的解法:

vector<vector<string>> groupAnagrams(vector<string>& strs) 
{
    vector<vector<string>> res;
    map<string,vector<string>> vec;
    if(strs.empty()) return res;
    for(int i=0;i<strs.size();i++)
    {
        string temp=strs[i];
        sort(temp.begin(),temp.end());
        vec[temp].push_back(strs[i]);
    }
    map<string,vector<string>>::iterator it;
    for(auto it=vec.begin();it!=vec.end();it++)
    {
        res.push_back(it->second);
    }
    return res;
}

思路:
LeetCode刷题总结 -- 数组篇_第3张图片
自己试一题:
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

输入: "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3

示例 2:

输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1

示例 3:

输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

4、其余

其余巧妙设计的题目就不放这里了,今后要是再看到什么好的方法再放进来。

5、了解vector

#include 
using namespace std;

#include

//创建vector
vector<int> test;	//初始化一个Vector实例,用于存放int型数据,实例名字叫test
vector<int> test2 = test;	//以test1为标准创建test2

vector<int>test3(10);	//像这种,少用。上次用的时候,往里面插了一个数据之后就没办法插入了。何况STL会自己给你分配空间,用不着你操心。

//插入数据
test.insert(test.begin()+i,a);	//在第i个元素前插入a
test.insert(test.begin()+i,te2.begin(),te2.end());	
//插入一段相同数据类型数据,第一个参数放插入位置(指针/迭代器形式),第二三个参数放待插入元素起始位置

test.push_back(a);	//往尾部插入
//一般我们就用尾部插入

//删除元素
test.erase(test.begin());
test.erase(test.begin(),test.begin()+5);//删除区间(第一个元素到第五个元素)

test.clear();	//清空

test.pop_back();	//删除尾部元素

/*
遍历元素
当然,你可以使用数组下标形式访问元素,因为vector重载了 [] 操作,很方便,但是有诸多限制。
还有一个叫at()的函数,这个好用。

也可以使用迭代器:
*/

vector<int>::iterator it;	//初始化一个vector类型的迭代器
for(it = test.begin();it!=test.end();it++)	//从头遍历到尾
{
	cout<<*it<<endl;	//取出内容
}


//排序
#include
/*test.*/sort(test.begin(),test.end());	//从头到尾,默认从小到大排序
这里要非常注意,前面那个test. 被我注释掉了,因为sort是属于算法范畴,不是容器的类方法。

//一般排序都是要自定义排序的:
bool Comp(const int &a,const int &b)
{
    return a>b;
}
sort(test.begin(),test.end(),Comp);	//这样就降序排序。 

其他还有:
对于二维vector的大小问题、
vector> ret:ret中vector的条数:ret.size();
vector的大小:if( ret[0] != NULL ){ int sz = ret[0].size(); }

其他再说吧

你可能感兴趣的:(通俗点聊聊算法,刷题心得,数据结构,数据结构,算法,leetcode)