55跳跃游戏;46全排列;48旋转图像;242有效的字母异位词;49字母异位词分组;56合并区间

给定一个非负整数数组,你最初位于数组的第一个位置。

数组中的每个元素代表你在该位置可以跳跃的最大长度。

判断你是否能够到达最后一个位置。

示例 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;
       
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值