【算法题】递归树+哈希表+分治异或+双指针


1.vector与spring的结合

17. 电话号码的字母组合https://leetcode.cn/problems/letter-combinations-of-a-phone-number/

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

题解:

方法一:

复制代码
class Solution {
public:
    vector<string> letterCombinations(string digits) {
       // 1. 映射表定义
       string map[] = {
            "", "", "abc", "def", "ghi", "jkl",
            "mno", "pqrs", "tuv", "wxyz"
        };
        int num=0;
        // 2. 初始化结果容器
        vector<string> vv(1);
        vector<string> tmp;
        
        // 3. 遍历输入数字字符串
        for(auto e:digits)
        {
            tmp.clear();
            num=e-'0';
            
            // 4. 遍历当前数字对应的字母
            for(auto ee:map[num])
            {
                // 5. 将当前字母与已有组合合并
                for(string eee:vv)
                {
                    tmp.push_back(eee+ee);
                }
            }
            // 6. 更新结果
            vv=tmp;
        }
        return vv;
    }
};

思考:

1.为什么这里要重新定义一个tmp?

2.容器为什么初始化?

3.tmp为什么要clear?

方法二(递归树):

复制代码
class Solution {
public:
    string a[10]={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
    vector<string> v;
    int n;
    string s;
    void dfs(int dep,string t){ //除了深度,加一个变量t用于保存每层拼接的字符串
        if(dep==n){
            v.push_back(t);
            return;
        }
        for(char c:a[s[dep]-'0']){ //第i层深度取字符串第i个数字  
            dfs(dep+1,t+c); //t+c会直接拼接
        }
    }//2345
    vector<string> letterCombinations(string digits) {
        n=digits.size();
        s=digits;
        dfs(0,"");
        return v;
    }
};
相同逻辑,不同写法:
复制代码
class Solution {
public:
    vector<string> res;

    vector<string> letterCombinations(string digits) {
        if(digits == "") return {};
        dfs(digits,0);
        return res;
    }
    void dfs(string digits,int index){
        if(index == digits.length()){
            res.push_back(digits);
            return;
        }
        switch(digits[index]){
            case '2': digits[index] = 'a'; dfs(digits,index+1);
                      digits[index] = 'b'; dfs(digits,index+1);  
                      digits[index] = 'c'; dfs(digits,index+1);
                      break;
            case '3': digits[index] = 'd'; dfs(digits,index+1);
                      digits[index] = 'e'; dfs(digits,index+1);  
                      digits[index] = 'f'; dfs(digits,index+1);
                      break;  
            case '4': digits[index] = 'g'; dfs(digits,index+1);
                      digits[index] = 'h'; dfs(digits,index+1);  
                      digits[index] = 'i'; dfs(digits,index+1);
                      break;  
            case '5': digits[index] = 'j'; dfs(digits,index+1);
                      digits[index] = 'k'; dfs(digits,index+1);  
                      digits[index] = 'l'; dfs(digits,index+1);
                      break; 
            case '6': digits[index] = 'm'; dfs(digits,index+1);
                      digits[index] = 'n'; dfs(digits,index+1);  
                      digits[index] = 'o'; dfs(digits,index+1);
                      break;  
            case '7': digits[index] = 'p'; dfs(digits,index+1);
                      digits[index] = 'q'; dfs(digits,index+1);  
                      digits[index] = 'r'; dfs(digits,index+1);
                      digits[index] = 's'; dfs(digits,index+1);
                      break;  
            case '8': digits[index] = 't'; dfs(digits,index+1);
                      digits[index] = 'u'; dfs(digits,index+1);  
                      digits[index] = 'v'; dfs(digits,index+1);
                      break;  
            case '9': digits[index] = 'w'; dfs(digits,index+1);
                      digits[index] = 'x'; dfs(digits,index+1);  
                      digits[index] = 'y'; dfs(digits,index+1);
                      digits[index] = 'z'; dfs(digits,index+1);
                      break;   
        }
    }
};

方法三:(队列)

复制代码
class Solution 
{
private:
    unordered_map<char,string> letter_map{
        {'2',"abc"}, {'3',"def"}, {'4',"ghi"},
        {'5',"jkl"}, {'6',"mno"}, {'7',"pqrs"},
        {'8',"tuv"}, {'9',"wxyz"}
    };
    vector<string> res;
public:
    vector<string> letterCombinations(string digits) 
    {
        if(digits.empty())
            return res;
        
        queue<string> que;
        for(int i=0;i<digits.size();++i)
        {
            string letters = letter_map[digits[i]]; //数字对应的字符集
            if(0==i)
            {
                // 如果是第一个数字,就将第一个数字对应的字符集依次加入队列中去
                string temp;
                for(int j=0;j<letters.size();++j)
                {
                    temp = letters[j];
                    que.push(temp);
                }
            }
            else
            {
                int size = que.size(); //队列长度
                //计算出队列长度后,将队列中的每个元素挨个拿出来
                for(int j=0;j<size;++j)
                {
                    string temp = que.front();
                    que.pop();
                    //然后跟当前数字对应的字符集拼接,并再次放到队列中
                    for(int k=0;k<letters.size();++k)
                    {
                        que.push(temp+letters[k]);
                    }
                }
            }
        }
        while(!que.empty())
        {
            res.emplace_back(que.front());
            que.pop();
        }

        return res;
    }
}

2.双指针法

11. 盛最多水的容器https://leetcode.cn/problems/container-with-most-water/

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0)(i, height[i])

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

返回容器可以储存的最大水量。

说明:你不能倾斜容器

题解:

复制代码
class Solution {
public:
    int maxArea(vector<int>& height) {
        int left=0,right=height.size()-1;
        int maxi;
        while(left<right)
        {    
            if(height[right]>height[left])
            {
            maxi=max(maxi,(right-left)*height[left]);
            left++;
            }
            else{
            maxi=max(maxi,(right-left)*height[right]);
            right--;
            }
        }
        return maxi;
    }
};

思考:

会不会出现漏失数据的现象?为什么可以双指针?


3.找单身狗lll

260. 只出现一次的数字 IIIhttps://leetcode.cn/problems/single-number-iii/

给你一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。

你必须设计并实现线性时间复杂度的算法且仅使用常量额外空间来解决此问题。

题解:

方法一:(分治异或法)

复制代码
class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        if(nums.size()==2)
        return  nums;
        int val=0;
        for(int i=0;i<nums.size();i++)
        {
            val^=nums[i];//x1^x2
        }
        int index=getFirst1(val);
        int num1=0,num2=0;
        for(auto ch:nums)
        {
            if(((ch>>index)&1)==0)
            num1^=ch;
            else
            num2^=ch;
        }
        return {num1,num2};
        
    }
    int getFirst1(int val) {
    int index=0;
    while (((val&1)==0&&index<32))
    {
        val>>=1;// val=val/2
        index++;
    }
        return index;
    }
};

方法二:(哈希表)

复制代码
class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        unordered_map<int, int> freq;
        for (int num: nums) {
            ++freq[num];
        }
        vector<int> ans;
        for (const auto& [num, occ]: freq) {
            if (occ == 1) {
                ans.push_back(num);
            }
        }
        return ans;
    }
};

相关推荐
十五年专注C++开发10 小时前
fatal error C1189: #error: WinSock.h has already been included 的解决方案
c++·socket·boost
risc12345610 小时前
肌肉收缩会释放大量的肌细胞因子能抑制体内炎症因子
笔记
KJ_BioMed11 小时前
从PDB到高亲和力分子:De novo生成式计算化学Pipeline剖析
算法·生物医药·生物科研·科研干货·化合物设计
一个王同学12 小时前
从零到一 | CV转多模态大模型 | week17 | LLM 推理优化 & vLLM 详解
人工智能·深度学习·算法·机器学习·计算机视觉·vllm
jimy112 小时前
C语言模拟对象、方法:“函数指针+结构体“复用函数指针指向的函数体
c语言·开发语言
既然如此,那就开摆12 小时前
精读笔记06_CoCa
笔记
天外天-亮12 小时前
HBuilder X 使用 uview-plus 方式
开发语言·javascript·hbuilder x·uview-plus
三品吉他手会点灯13 小时前
嵌入式机器学习 - 学习笔记1.1.1 - 什么是机器学习?
c语言·人工智能·笔记·嵌入式硬件·学习·机器学习
qq57521731913 小时前
Notepad++下载和安装
笔记·notepad++·记事本
木木子2213 小时前
[特殊字符] 音乐播放器——状态驱动的多媒体控制
android·开发语言·华为·php·harmonyos