给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个位置。
示例 1:
输入: [2,3,1,1,4]
输出: true
解释: 我们可以先跳 1 步,从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。
示例 2:
输入: [3,2,1,0,4]
输出: false
解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 , 所以你永远不可能到达最后一个位置。
class Solution {//超时
public:
vector<int> nums;
bool canJump(vector<int>& nums) {
if(nums.size()==0)return false;
this->nums=nums;
return helper(0);
}
int helper(int pos){
if(pos==nums.size()-1)return true;
for(int i=1;i<=nums[pos]&&pos+i<nums.size();i++)
if(helper(pos+i))return true;
return false;
}
};
class Solution {
public:
bool canJump(vector<int>& nums) {
if(nums.size()==0)return false;
int maxPos=0;
for(int i=0;i<nums.size()&&i<=maxPos&&maxPos<nums.size()-1;++i){
maxPos=max(maxPos,nums[i]+i);
}
if(maxPos>=nums.size()-1)return true;
else return false;
}
};
给定一个 没有重复 数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
//回溯法三要素:分支含义+分支数目+返回条件
//回溯框架:
vector<vector<int>> res;//最终结果存放
vector<int> path;//路径
vector<int> nums;//选择列表
void backTrack(辅助变量):
if(满足结束条件){
res.push_back(path);
return;
}
for(根据分支条件,遍历选择列表)
path.push_back(XXX);//选择
backtrack(...)
path.pop_back();//撤销选择
class Solution {
public:
vector<vector<int>> res;
vector<int> path;
vector<int> nums;
vector<vector<int>> permute(vector<int>& nums) {
if(nums.size()==0)return {};
this->nums=nums;
vector<bool> covered(nums.size(),false);
helper(0,covered);
return res;
}
void helper(int count,vector<bool> &covered){
if(count==nums.size()){
res.push_back(path);
return;
}
for(int i=0;i<nums.size();++i){
if(!covered[i]){
path.push_back(nums[i]);
covered[i]=true;
helper(count+1,covered);
covered[i]=false;
path.pop_back();
}
}
}
};
给定一个 n × n 的二维矩阵表示一个图像。
将图像顺时针旋转 90 度。
说明:
你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要使用另一个矩阵来旋转图像。
示例 1:
给定 matrix =
[
[1,2,3],
[4,5,6],
[7,8,9]
],
原地旋转输入矩阵,使其变为:
[
[7,4,1],
[8,5,2],
[9,6,3]
]
示例 2:
给定 matrix =
[
[ 5, 1, 9,11],
[ 2, 4, 8,10],
[13, 3, 6, 7],
[15,14,12,16]
],
原地旋转输入矩阵,使其变为:
[
[15,13, 2, 5],
[14, 3, 4, 1],
[12, 6, 8, 9],
[16, 7,10,11]
]
class Solution {//O(N^2)
public:
void rotate(vector<vector<int>>& matrix) {
int n=matrix.size();
for(int i=0;i<n;++i)
for(int j=0;j<i;++j)
swap(matrix[i][j],matrix[j][i]);
for(int i=0;i<n;++i)
for(int j=0;j<n>>1;++j)
swap(matrix[i][j],matrix[i][n-1-j]);
}
};
class Solution {//O(N)
public:
void rotate(vector<vector<int>>& matrix) {
//[i][j]->[j][n-1-i]->[n-1-i][n-1-j]->[n-1-j][i]->[i][j]
int n=matrix.size();
for(int i=0;i<n>>1;++i)
for(int j=0;j<(n+1)>>1;++j){
int temp=matrix[i][j];
matrix[i][j]=matrix[n-1-j][i];
matrix[n-1-j][i]=matrix[n-1-i][n-1-j];
matrix[n-1-i][n-1-j]=matrix[j][n-1-i];
matrix[j][n-1-i]=temp;
}
}
};
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
示例 1:
输入: s = "anagram", t = "nagaram"
输出: true
示例 2:
输入: s = "rat", t = "car"
输出: false
说明:
你可以假设字符串只包含小写字母。
进阶:
如果输入字符串包含 unicode 字符怎么办?你能否调整你的解法来应对这种情况?
class Solution {//方法一:map计数
public:
bool isAnagram(string s, string t) {
if(s.size()!=t.size())return false;
if(s.size()==0)return true;
unordered_map<char,int> m;
for(auto i:s)
++m[i];
for(auto i:t)
if(m.find(i)==m.end()||m[i]==0)return false;
else --m[i];
return true;
}
};
//方法二:排序
class Solution {
public:
bool isAnagram(string s, string t) {
if(s.size()!=t.size())return false;
if(s.size()==0)return true;
sort(s.begin(),s.end());
sort(t.begin(),t.end());
return s==t;
}
};
给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。
示例:
输入: ["eat", "tea", "tan", "ate", "nat", "bat"],
输出:
[
["ate","eat","tea"],
["nat","tan"],
["bat"]
]
说明:
所有输入均为小写字母。
不考虑答案输出的顺序。
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
vector<vector<string>>res;
unordered_map<string,vector<string>> m;//
for(int i=0;i<strs.size();++i){
string s=strs[i];
sort(s.begin(),s.end());
m[s].push_back(strs[i]);
}
for(auto i:m)
res.push_back(i.second);//
return res;
}
};
//map<string,vector<string>> m + vector<vector<string>> res
//改成map<string,int(表示res第一维下标)> m + vector<vector<string>> res
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
vector<vector<string>>res;
unordered_map<string,int> m;
for(int i=0,index=0;i<strs.size();++i){
string s=strs[i];
sort(s.begin(),s.end());
if(m.find(s)!=m.end())
res[m[s]].push_back(strs[i]);
else{
m[s]=index++;
res.push_back(vector<string>{strs[i]});
}
}
return res;
}
};
给出一个区间的集合,请合并所有重叠的区间。
示例 1:
输入: [[1,3],[2,6],[8,10],[15,18]]
输出: [[1,6],[8,10],[15,18]]
解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
示例 2:
输入: [[1,4],[4,5]]
输出: [[1,5]]
解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。
class Solution {
public:
vector<vector<int>> merge(vector<vector<int>>& intervals) {
if(intervals.size()==0)return {};
sort(intervals.begin(),intervals.end());
vector<vector<int>> res;
res.push_back(intervals[0]);
for(int i=1,resIndex=0;i<intervals.size();++i)
if(intervals[i][0]>res[resIndex][1]){
res.push_back(intervals[i]);
++resIndex;
}
else if(intervals[i][1]>res[resIndex][1])
res[resIndex][1]=intervals[i][1];
return res;
}
}