leetcode
[hot] 1. 两数之和
题目
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。你可以按任意顺序返回答案。
题解
map解决问题,一边遍历数组一边寻找target-nums[i]是否存在于map中,这样用O(n)的时间就能够找到目标pair,示例代码如下:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
int length = nums.size();
map<int, int> m;
m[nums[0]] = 0;
for (int i = 1; i < length; ++i) {
if (m.count(target - nums[i]) > 0) {
return {m[target - nums[i]], i};
}
m[nums[i]] = i;
}
return vector<int>();
}
};
复杂度
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
n
)
O(n)
O(n),map的辅助空间
[hot] 49. 字母异位词分组
题目
给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。字母异位词 是由重新排列源单词的所有字母得到的一个新单词。
示例 1:
输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
示例 2:
输入: strs = [""]
输出: [[""]]
示例 3:
输入: strs = ["a"]
输出: [["a"]]
题解
通过map映射进行求解,示例代码如下所示:
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
vector<vector<string>> res;
map<string, vector<string>> m;
for (const auto& str: strs) {
string s = string(26, '0');
for (const auto& c: str) {
++s[c - 'a'];
}
m[s].emplace_back(str);
}
for (const auto& elem: m) {
res.emplace_back(elem.second);
}
return res;
}
};
复杂度
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
n
)
O(n)
O(n)
[hot] 347. 前 K 个高频元素
题目
给定一个非空的整数数组,返回其中出现频率前 k 高的元素。
示例 1:
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
示例 2:
输入: nums = [1], k = 1
输出: [1]
题解
桶排序解决问题,示例代码如下所示:
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k) {
map<int, int> m;
for (auto& num: nums) {
if (m.count(num) > 0) {
++m[num];
} else {
m[num] = 1;
}
}
int length = nums.size();
vector<vector<int>> ctnr(length + 1, vector<int>());
for (auto& elem: m) {
auto& key = elem.first;
auto& value = elem.second;
ctnr[value].emplace_back(key);
}
vector<int> res;
for (int i = length; res.size() < k && i >= 0; --i) {
for (int j = 0; res.size() < k && j < ctnr[i].size(); ++j) {
res.emplace_back(ctnr[i][j]);
}
}
return res;
}
};
复杂度
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
n
)
O(n)
O(n)
763. 划分字母区间
题目
给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s 。返回一个表示每个字符串片段的长度的列表。
示例 1:
输入:s = "ababcbacadefegdehijhklij"
输出:[9,7,8]
解释:
划分结果为 "ababcbaca"、"defegde"、"hijhklij" 。
每个字母最多出现在一个片段中。
像 "ababcbacadefegde", "hijhklij" 这样的划分是错误的,因为划分的片段数较少。
示例 2:
输入:s = "eccbbbbdec"
输出:[10]
题解
直接上代码:
class Solution {
public:
vector<int> partitionLabels(string s) {
vector<int> last(26);
int length = s.size();
for (int i = 0; i < length; ++i) {
last[s[i] - 'a'] = i;
}
vector<int> p;
int start = 0, end = 0;
for (int i = 0; i < length; ++i) {
end = max(end, last[s[i] - 'a']);
if (i == end) {
p.emplace_back(end - start + 1);
start = end + 1;
}
}
return p;
}
};
复杂度
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
字母表
)
O(字母表)
O(字母表)