腾讯百度阿里华为常见算法面试题TOP100(6):回溯、二分查找、二叉树

news2024/9/20 2:58:20

之前总结过字节跳动TOP50算法面试题:

字节跳动常见算法面试题top50整理_沉迷单车的追风少年-CSDN博客_字节算法面试题

回溯

46.全排列

class Solution {
private:
    vector<vector<int> > ans;
    void dfs(vector<int>& nums, vector<int>& temp, int index) {
        if (temp.size() == nums.size()) {
            ans.push_back(temp);
            return;
        }
        for (int i = 0; i < nums.size(); i++) {
            if (find(temp.begin(), temp.end(), nums[i]) == temp.end()) {
                temp.push_back(nums[i]);
                dfs(nums, temp, i);
                temp.pop_back();
            }

        }
    }
public:
    vector<vector<int>> permute(vector<int>& nums) {
        vector<int> temp;
        dfs(nums, temp, 0);
        return ans;
    }
};

78.子集

class Solution {
private:
    vector<vector<int> > ans;
    void dfs(vector<int>& nums, vector<int>& temp, int index) {
        if (find(ans.begin(), ans.end(), temp) == ans.end()) {
            ans.push_back(temp);
        }
        if (index >= nums.size()) {
            return;
        }
        for (int i = index; i < nums.size(); i++) {
            temp.push_back(nums[i]);
            dfs(nums, temp, i + 1);
            temp.pop_back();
        }
    }
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        vector<int> temp;
        dfs(nums, temp, 0);
        return ans;
    }
};

17.电话号码的字母组合

class Solution {
private:
    vector<string> ans;
    vector<string> sList={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"}; //字符表
    void backtrack(string& digits, string temp, int index) {
        if (index == digits.size()) {
            ans.push_back(temp);
            return;
        }
        string s = sList[digits[index] - '0'];
        // for循环横向遍历,递归纵向遍历
        for (int i = 0; i < s.size(); i++) {
            temp.push_back(s[i]);
            backtrack(digits, temp, index + 1);
            temp.pop_back();
        }
    }
public:
    vector<string> letterCombinations(string digits) {
        if (digits.empty()) {
            return {};
        }
        backtrack(digits, {}, 0);
        return ans;
    }
};

 39.组合总和

class Solution {
private:
    vector<vector<int> > ans;
    void backtrack(vector<int>& candidates, int& target, vector<int> temp, int cursum, int index) {
        if (cursum == target) {
            ans.push_back(temp);
            return;
        }
        for (int i = index; i < candidates.size(); i++) {
            // 剪枝
            if (cursum + candidates[i] > target) {
                break;
            }
            temp.push_back(candidates[i]);
            backtrack(candidates, target, temp, cursum + candidates[i], i);
            temp.pop_back();
        }
    }
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        sort(candidates.begin(), candidates.end());
        backtrack(candidates, target, {}, 0, 0);
        return ans;
    }
};

22.括号生成

class Solution {
private:
    vector<string> ans;
    void backtrack(int left, int right, int n, string s) {
        if (left == n && right == n) {  // 左右都拼完了终止
            ans.push_back(s);
            return;
        }
        if (left < n) {     // 左边括号没拼满拼接左边
            backtrack(left + 1, right, n, s + '(');
        }
        if (right < left) {  // 右边括号比左边少拼接右边
            backtrack(left, right + 1, n, s + ')');
        } 
    }
public:
    vector<string> generateParenthesis(int n) {
        // DFS+回溯
        // left代表左边拼了的括号数
        // right代表右边拼的括号数
        backtrack(0, 0, n, "");
        return ans;
    }
};

79.单词搜索

class Solution {
private:
    // 剪枝操作,当找到路径的时候终止 
    bool flag = false;
public:
    bool exist(vector<vector<char>>& board, string word) {
        if (board.empty() || board.size() == 0 || board[0].size() == 0)
            return false;
        // DFS+回溯+剪枝
        for (int i = 0; i<board.size(); i++) {
            for (int j = 0; j<board[0].size(); j++) {
                if (dfs(board, i, j, word, 0))
                    return true;
            }
        }
        return false;
    }
    // 传入引用直接在原位置上进行操作,不需要新建变量与赋值,节省时间开销和空间开销
    bool dfs(vector<vector<char>>& board, int i, int j, const string& word, int cur) {
        // 先列出终止条件
        if (cur == word.size()) {
            flag = true;
            return true;
        }
        // 回溯中心处理环节
        if (i < 0 || i>=board.size() || j < 0 || j >= board[0].size() || word[cur] != board[i][j])
            return false;
        // 分别标记上下左右每次搜索是否成功
        bool flag1, flag2, flag3, flag4;
        if (!flag) {
            // 先将board[i][j]拿出来用
            board[i][j] = '.';
            flag1 = dfs(board, i+1, j, word, cur+1);
            flag2 = dfs(board, i-1, j, word, cur+1);
            flag3 = dfs(board, i, j+1, word, cur+1);
            flag4 = dfs(board, i, j-1, word, cur+1);
            // 再将board[i][j]放回去,还原回溯现场
            board[i][j] = word[cur];
            // 任意一个方向成功即为此处搜索成功,返回true
            return flag1 ||flag2 || flag3 || flag4;
        }
        return true;
    }
};

131.分割回文串 

class Solution {
public:
    vector<vector<string>> partition(string &s) {
        backtravel(s, 0, s.size()-1);
        return ans;
    }
private:
    vector<vector<string> > ans;
    vector<string> temp;
    void backtravel(const string &s, const int &left, const int &right) {
        //到字符串末尾了,将本次结果记录下来
        if (left > right) {
            ans.push_back(temp);
            return;
        }
        //从index为a开始截取长度为1,2,3..的子串进行验证,成功则用剩下的部分递归
        for (int i = 1; i <= right - left + 1; i++) {
            if (isHuiwen(s.substr(left, i))) {
                temp.push_back(s.substr(left, i));
                // 以上一次成功的位置为起点再次进行递归
                backtravel(s, left+i, right);
                temp.pop_back();
            }
        }
    }
    bool isHuiwen(const string &s) {
        int left = 0, right = s.size() - 1;
        while (left <= right) {
            if (s[left] != s[right])
                return false;
            left++;
            right--;
        }
        return true;
    }
};

51.N皇后

class Solution {
private:
    vector<vector<string>> ans;    
    // n 为输入的棋盘大小
    // row 是当前递归到棋盘的第几行了
    void backtrack(int n, int row, vector<string> chessboard) {
        if (row == n) {
            ans.push_back(chessboard);
            return;
        }
        for (int col = 0; col < n; col++) {
            if (isVaild(chessboard, row, col)) {
                chessboard[row][col] = 'Q';
                backtrack(n, row + 1, chessboard);
                chessboard[row][col] = '.';
            }
        }
    }
    // 判断是否合法
    bool isVaild(vector<string> chessboard, int row, int col) {
        // 同列不能用皇后
        for (int i = 0; i < row; i++) {
            if (chessboard[i][col] == 'Q') {
                return false;
            }
        }
        // 斜45不能用皇后
        for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
            if (chessboard[i][j] == 'Q') {
                return false;
            }
        }
        // 斜135不能用皇后
        for (int i = row - 1, j = col + 1; i >= 0 && j < chessboard.size(); i--, j++) {
            if (chessboard[i][j] == 'Q') {
                return false;
            }
        }
        return true;
    }
public:
    vector<vector<string>> solveNQueens(int n) {
        vector<string> chessboard(n, string(n, '.'));
        backtrack(n, 0, chessboard);
        return ans;
    }
};

二分搜索

35.搜索插入位置

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int left = 0;
        int right = nums.size() - 1;
        while (left <= right) {
            int mid = (left + right) / 2;
            if (nums[mid] > target) {
                right = mid - 1;
            } else if (nums[mid] < target) {
                left = mid + 1;
            } else {
                return mid;
            }
        }
        return right + 1;
    }
};

74.搜索二维矩阵

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        // 选择左下角开始比较
        if(matrix.size()==0)
            return false;
        int i = 0; 
        int j = matrix[0].size()-1;
        while (i<matrix.size()&&j>=0) {
            if ( matrix[i][j]>target ) {
                j--;
            }else if (matrix[i][j]<target) {
                i++;
            }else {
                return true;
            }
        }
        return false;
    }
};

34.在排序数组中查找元素的第一个和最后一个位置

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        int leftBorder = getLeftBorder(nums, target);
        int rightBorder = getRightBorder(nums, target);
        // 情况一: target在数组范围的左边或者右边
        if (leftBorder == -2 || rightBorder == -2) {
            return {-1, -1};
        }
        // 情况三: target在数组范围内且存在
        if (rightBorder - leftBorder > 1) {
            return {leftBorder + 1, rightBorder - 1};
        }
        // 情况二: target在数组范围内但是不存在
        return {-1, -1};
    }
private:
     int getRightBorder(vector<int>& nums, int target) {
        int left = 0;
        int right = nums.size() - 1;
        int rightBorder = -2; // 记录一下rightBorder没有被赋值的情况
        while (left <= right) {
            int middle = left + ((right - left) / 2);
            if (nums[middle] > target) {
                right = middle - 1;
            } else { // 寻找右边界,nums[middle] == target的时候更新left
                left = middle + 1;
                rightBorder = left;
            }
        }
        return rightBorder;
    }
    int getLeftBorder(vector<int>& nums, int target) {
        int left = 0;
        int right = nums.size() - 1;
        int leftBorder = -2; // 记录一下leftBorder没有被赋值的情况
        while (left <= right) {
            int middle = left + ((right - left) / 2);
            if (nums[middle] >= target) { // 寻找左边界,nums[middle] == target的时候更新right
                right = middle - 1;
                leftBorder = right;
            } else {
                left = middle + 1;
            }
        }
        return leftBorder;
    }
};

33.搜索旋转排序数组 

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int ans = -1;
        // 二分
        // 将数组一分为二,其中一定有一个是有序的,另一个可能是有序,也能是部分有序。此时有序部分用二分法查找。无序部分再一分为二,其中一个一定有序,另一个可能有序,可能无序。就这样循环.
        int left = 0;
        int right = nums.size() - 1;
        while (left <= right) {
            int mid = (left + right) / 2;
            if (nums[mid] == target) {
                return mid;
            } else if (nums[mid] > nums[right]) {  // 无序在右半段
                if (target < nums[mid] && target >= nums[left]) {    // 判断target是否在有序的半段
                    right = mid - 1;
                } else {
                    left = mid + 1;
                }
            } else {    // 无序在左半段
                if (target > nums[mid] && target <= nums[right]) {   // 判断target是否在有序的半段
                    left = mid + 1;
                } else {
                    right = mid - 1;
                }
            }
        }
        return ans;
    }
};

153.寻找旋转排序数组中的最小值 

class Solution {
public:
    int findMin(vector<int>& nums) {
        int left = 0;
        int right = nums.size() - 1;
        while (left < right) {
            // 取中间值
            int mid = (right + left) / 2;
            // 如果中间值小于最大值,则最大值减小
            if (nums[mid] < nums[right]) {
                right = mid;
            } else { // 如果中间值大于最大值,则最小值变大
                left = mid + 1;
            }
        }
        return nums[left];
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2147687.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

西南民族大学若尔盖国家野外台站王志强研究员团队在树皮生态化学计量学研究中取得新进展!

本文首发于“生态学者”微信公众号&#xff01; 近日&#xff0c;西南民族大学四川若尔盖高寒湿地生态系统国家野外科学观测研究站王志强研究员团队在植物科学顶级期刊New Phytologist和环境科学与生态学TOP期刊Science of the Total Environment分别以“Global patterns and …

【Java】网络编程-地址管理-IP协议后序-NAT机制-以太网MAC机制

&#x1f308;个人主页&#xff1a;努力学编程’ ⛅个人推荐&#xff1a; c语言从初阶到进阶 JavaEE详解 数据结构 ⚡学好数据结构&#xff0c;刷题刻不容缓&#xff1a;点击一起刷题 &#x1f319;心灵鸡汤&#xff1a;总有人要赢&#xff0c;为什么不能是我呢 &#x1f434…

AI大模型之旅-大模型为的微调参数详解

output model.generate( inputs.input_ids, max_lengthmax_length, do_sampledo_sample, temperaturetemperature, top_ptop_p, top_ktop_k ) 大模型文本常用参数为以上几个&#xff0c;下面我们详细解析下&#xff1a; 初解&#xff1a; max_length 定义&#xff1a;生成的…

MacOS安装homebrew,jEnv,多版本JDK

1 安装homebrew homebrew官网 根据官网提示&#xff0c;运行安装命令 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"安装后&#xff0c;bash会提示执行两条命令 (echo; echo eval "$(/opt/homebrew/b…

简明linux系统编程--共享内存消息队列信号量

目录 1.父子进程共享内存 1.1基本说明 1.2主要步骤 1.3shmget函数介绍​编辑 1.4函数返回值 1.5shmat函数介绍 1.6shmdt函数介绍 1.7结合代码理解 2.非亲缘关系的进程的共享内存通信 2.1和上面的区别 2.2如何通信 2.3具体代码 3.父子进程消息队列 4.非亲缘关系的进…

极狐GitLab 重要安全版本:17.3.3, 17.2.7, 17.1.8, 17.0.8, 16.11.10

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 学习极狐GitLab 的相关资料&#xff1a; 极狐GitLab 官网极狐…

BitLocker硬盘加密的详细教程分享

硬盘加密是将数据转换为一种只有授权用户才能读取的形式。通过使用加密算法&#xff0c;硬盘上的数据在存储时被加密&#xff0c;只有输入正确的密钥或密码才能解密和访问这些数据。 硬盘加密的重要性 数据是现代社会的重要资产&#xff0c;保护这些数据免受非法访问和窃取至关…

Mobile net V系列详解 理论+实战(2)

Mobilenet 系列 实践部分一、数据集介绍二、模型整体框架三、模型代码详解四、总结 实践部分 本章针对实践通过使用pytorch一个实例对这部分内容进行吸收分析。本章节采用的源代码在这里感兴趣的读者可以自行下载操作。 一、数据集介绍 可以看到数据集本身被存放在了三个文件…

处理RabbitMQ连接和认证问题

在使用RabbitMQ进行消息队列管理时&#xff0c;我们可能会遇到各种连接和认证问题。本文将介绍如何诊断和解决这些问题&#xff0c;并通过使用RabbitMQ的管理端进行登录验证来确保配置正确。 1. 问题概述 在最近的一次部署中&#xff0c;我们遇到了两个主要问题&#xff1a; …

一对一,表的设计

表很大&#xff0c;比如用户 用户登录只需要部分数据&#xff0c;所以把用户表拆成两个表 用户登录表 用户信息表 一对一设计有两种方案&#xff1a; 加外键&#xff0c;唯一 主键共享

学生考试成绩老师发布平台

老师们一直肩负着传授知识与评估学生学习成果的双重责任。其中&#xff0c;发布学生考试成绩是教学过程中不可或缺的一环。然而&#xff0c;传统的成绩发布方式往往繁琐且耗时。老师们需要手动整理成绩&#xff0c;然后通过电话、短信或电子邮件逐一通知学生和家长&#xff0c;…

Jenkins设置自动拉取代码后怎么设置自动执行构建任务?

在 Jenkins 中设置自动拉取代码后&#xff0c;可以通过以下步骤设置自动执行构建任务&#xff1a; 一、配置构建触发器 打开已经设置好自动拉取代码的 Jenkins 任务。在 “构建触发器” 部分&#xff0c;除了 “Poll SCM”&#xff08;用于定时检查代码仓库更新&#xff09;外…

Mybatis 和 数据库连接

第一次要下载驱动 查询数据库版本 但是在idea查看数据库我不行&#xff0c;插件我也装了&#xff0c;然后我在尝试改版本。也不行。 爆错 感觉还是插件的问题。先不弄了&#xff0c;影响不大。 但是加载了这个&#xff0c;能在idea写sql语句&#xff0c;还能有提示。

【IPOL阅读】点云双边滤波

文章目录 简介点云滤波处理结果 简介 IPOL&#xff0c;即Image Processing On Line&#xff0c;理论上是一个期刊&#xff0c;但影响因子很低&#xff0c;只是个SCIE&#xff0c;按理说没什么参考价值。但是&#xff0c;这个网站的所有文章&#xff0c;都附带了源代码和演示窗…

【三步搭建 本地 编程助手 codegeex】

这里写目录标题 第一步 ollama安装常见报错 第二步 下载启动模型下载启动模型常见问题 第三步配置codegeex安装插件本地配置 其他 如果可以联网&#xff0c;vscode装个codegeex插件即可&#xff0c;本次搭建的本地编程助手&#xff0c;解决因安全问题完全无网络的情况下的编程助…

诗文发布模板(python代码打造键盘录入诗文自动排版,MarkDown源码文本)

python最好用的f-string&#xff0c;少量代码打造键盘录入诗文自动排版。 (笔记模板由python脚本于2024年09月19日 19:11:50创建&#xff0c;本篇笔记适合喜欢写诗的pythoner的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&am…

新手入门大模型教程(非常详细)零基础入门到精通,收藏这一篇就够了

目前大模型非常的火&#xff0c;国内开始流行大模型应用&#xff0c;那么作为程序员对于大模型有什么要了解和学习的我们今天就来研究下。 深度学习基础 因为大模型也是人工智能&#xff0c;人工智能就要先学习一下深度学习&#xff0c;深度学习是机器学习领域中的一个方向。…

Linux通过yum安装Docker

目录 一、安装环境 1.1. 旧的docker包卸载 1.2. 安装常规环境包 1.3. 设置存储库 二、安装Docker社区版 三、解决拉取镜像失败 3.1. 创建文件目录/etc/docker 3.2. 写入镜像配置 https://docs.docker.com/engine/install/centos/ 检测操作系统版本&#xff0c;我操作的…

英飞凌最新AURIX™TC4x芯片介绍

概述: 英飞凌推出最新的AURIX™TC4x系列,突破了电动汽车、ADAS、汽车e/e架构和边缘应用人工智能(AI)的界限。这一代面向未来的微控制器将有助于克服安全可靠的处理性能和效率方面的限制。客户将可缩短快速上市时间并降低整体系统成本。为何它被称为汽车市场新出现的主要颠覆…

SourceTree保姆级教程1:(克隆,提交,推送)

本人认为sourceTree 是最好用的版本管理工具&#xff0c;下面将讲解下sourceTree 客户端工具 克隆&#xff0c;提交&#xff0c;推送 具体使用过程&#xff0c;废话不多说直接上图。 使用步骤&#xff1a; 首先必须要先安装Git和sourceTree&#xff0c;如何按照参考其它文章&…