LeetCode: 16 回溯

2023-10-27

Letter Combinations of a Phone Number

"""这种题就是DFS,递归+一堆传引用。
迭代解法见http://www.cnblogs.com/grandyang/p/4452220.html,也可以用队列实现。
"""
class Solution {
public:
    void helper(const string& digits, vector<string>& res, const vector<string>& m, int n, string & re){
        if(digits.empty()){
            res = {};
            return;
        }

        string tmps = m[digits[n]-'0'];
        for(char c:tmps){
            re += c;
            helper(digits, res, m, n+1, re);
            if(n==digits.size()-1){
                res.push_back(re);
            }
            re.pop_back();
        }
    }
    vector<string> letterCombinations(string digits) {
        if(digits.empty())
            return {};
        vector<string> m={"","","abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
        vector<string> res;
        string re="";
        helper(digits, res, m, 0, re);
        return res;
    }
};

Remove Nth Node From End of List

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* slow = head;
        ListNode* fast = head;
        for(int i=0;i<n;i++)
            fast = fast->next;

        if(!fast)
            return slow->next;

        while(fast->next){
            slow = slow->next;
            fast = fast->next;
        } //slow停在要删的节点前面一个节点

        slow->next = slow->next->next;

        return head;
    }
};

Generate Parentheses

"""DFS递归法和前面那题很像

"""
class Solution {
public:
    void helper(vector<string>& res, int left, int right, string re){
        if(left > right)
            return;
        if(right == 0 && left == 0)
            res.push_back(re);
        else{
            if(left) helper(res, left-1, right, re+"(");
            if(right) helper(res, left, right-1, re+")");
        }
    }
    vector<string> generateParenthesis(int n) {
        vector<string> res;
        string re="";
        int left = n, right = n;
        helper(res, left, right, re);
        return res;
    }
};

Swap Nodes in Pairs

"""递归
"""
class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        if(!head || !head->next)
            return head;
        ListNode* tmp = head->next;
        head->next = swapPairs(head->next->next);
        tmp->next = head;
        return tmp;
    }
};

Next Permutation

class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        //  12544321 -> 
        bool flag = true;
        int idx = 0;
        for(int i=nums.size()-1;i>0;i--){
            flag = nums[i]<=nums[i-1];
            if(!flag){
                idx = i;
                break;
            }
        }

        if(flag){
            sort(nums.begin(), nums.end());
        }
        else{
            int idx1 = idx-1;
            for(int i=nums.size()-1;i>=idx;i--){
                if(nums[i]>nums[idx1]){
                    int tmp = nums[i];
                    nums[i] = nums[idx1];
                    nums[idx1] = tmp;
                    sort(nums.begin()+idx1+1, nums.end());//可以换为逆序,仔细观察规律
                    return;
                }
            }
        }

    }
};

Search in Rotated Sorted Array

class Solution {
public:
    int helper(vector<int>& nums, int i, int j, int target) {
        if(nums.empty() || i>j)
            return -1;

        int split = i + (j-i)/2;
        if(target == nums[split])
            return split;//split;

        if(nums[split]<nums[j]){
            if(target>nums[split] && target<=nums[j])
                return helper(nums, split+1, j, target);
            else
                return helper(nums, i, split-1, target);
        }
        else{        
            if(target>=nums[i] && target<nums[split])
                return helper(nums, i, split-1, target);
            else
                return helper(nums, split+1, j, target);
        }
    }

    int search(vector<int>& nums, int target) {
        return helper(nums, 0, nums.size()-1, target);
    }
};

Search for a Range

"""类似上一题,只需要用一个分支的二分法。
"""
class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        vector<int> res = {-1,-1};
        int i=0, j=nums.size()-1;
        while(i<=j){
            int mid = i+(j-i)/2;
            if(nums[mid]==target){
                int k = mid;
                while(k>=i && nums[k] == target)
                    k--;
                res[0] = k+1;
                while(mid<=j && nums[mid] == target)
                    mid++;
                res[1] = mid-1;
                return res;
            }
            else if(nums[mid]>target){
                j = mid-1;
            }
            else
                i = mid+1;
        }

        return res;
    }
};
"""也可以单独搜索左边界和右边界: http://www.cnblogs.com/grandyang/p/4409379.html
"""
class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        vector<int> res = {-1,-1};
        if(nums.empty())
            return res;
        int i=0, j=nums.size()-1;
        while(i<=j){
            int mid = i+(j-i)/2;
            if(nums[mid]>=target)
                j = mid-1;
            else
                i = mid+1;
        }
        if(j+1>=nums.size() || nums[j+1]!=target)//要找的最靠右边的比target小的数字nums[j]恰好是数组最后一个元素的情况,此时nums[j+1]不存在,之前的更新一直是把i往右边移动
            return {-1,-1};
        else
            res[0] = j+1;

        j = nums.size()-1;
        while(i<=j){
            int mid = i+(j-i)/2;
            if(nums[mid]>target)
                j = mid-1;
            else
                i = mid+1;
        }
        res[1] = i-1;

        return res;
    }
};

Valid Sudoku

class Solution {
public:
    bool isValidSudoku(vector<vector<char>>& board) {
        int in_rows[9][9] = {0}, in_cols[9][9] = {0}, in_box[9][9] = {0};
        for(int i=0;i<board.size();i++){
            for(int j=0;j<board[i].size();j++){
                if(board[i][j]!='.'){
                    int tmp = board[i][j] - '0' - 1;
                    int loc = 3 * (i / 3) + j / 3;
                    if(in_rows[i][tmp]||in_cols[j][tmp]||in_box[loc][tmp])
                        return false;
                    else{
                        in_rows[i][tmp] = 1;
                        in_cols[j][tmp] =1;
                        in_box[loc][tmp] = 1;
                    }
                }
            }
        }
        return true;
    }
};

Combination Sum

class Solution {
public:
    void helper(vector<int> & candidates, int target, vector<vector<int>>& res, vector<int>& re, int loc){
        if(target<0)
            return;
        else if(target == 0){
            res.push_back(re);
            return;
        }
        else{
            for(int i=loc;i<candidates.size();i++){
                re.push_back(candidates[i]);
                helper(candidates, target-candidates[i], res, re, i);
                re.pop_back();
            }
        }
    }
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        if(candidates.empty())
            return {};
        vector<vector<int>> res;
        vector<int> re;
        helper(candidates, target, res, re, 0);
        return res;
    }
};

Combination Sum II

class Solution {
public:
    void helper(vector<int> & candidates, int target, vector<vector<int>>& res, vector<int>& re, int loc){
        if(target<0)
            return;
        else if(target == 0){
            res.push_back(re);
            return;
        }
        else{
            for(int i=loc;i<candidates.size();i++){
                if (i > loc && candidates[i] == candidates[i - 1]) continue; //避免1,7和7,1这样的重复
                re.push_back(candidates[i]);
                helper(candidates, target-candidates[i], res, re, i+1); //同一个位置的数字不能多次使用
                re.pop_back();
            }
        }
    }
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        if(candidates.empty())
            return {};
        sort(candidates.begin(), candidates.end());
        vector<vector<int>> res;
        vector<int> re;
        helper(candidates, target, res, re, 0);
        return res;        
    }
};

Multiply Strings

"""这其实一种表示和计算超大数字的方法,即用字符串或数组
"""
class Solution {
public:
    string multiply(string num1, string num2) {
        string res = "";
        int n1 = num1.size(), n2 = num2.size();
        vector<int> v(n1+n2,0);

        for(int i=n1-1;i>=0;i--)
            for(int j=n2-1;j>=0;j--){
                v[i+j+1] += (num1[i]-'0')*(num2[j]-'0');
            }

        int carry = 0;
        for(int i=n1+n2-1;i>=0;i--){
            v[i] += carry;
            carry = v[i]/10;
            v[i] %=10;
        }

        int k = 0;
        while(v[k] == 0)
            k++;
        if(k>=v.size())
            return "0";
        for(int i=k;i<n1+n2;i++)
            res+=('0'+v[i]);

        return res;
    }
};

Permutations

class Solution {
public:
    void helper(vector<int>& nums,  vector<vector<int>>& res, vector<int>& re, vector<int>& visited){
        if(re.size() == nums.size())
            res.push_back(re);
        else
            for(int i=0;i<nums.size();i++){
                if(!visited[i]){
                    visited[i] = 1;
                    re.push_back(nums[i]);
                    helper(nums, res, re, visited);
                    re.pop_back();
                    visited[i] = 0;
                }
            }
    }
    vector<vector<int>> permute(vector<int>& nums) {
        if(nums.empty())
            return {};
        vector<vector<int>> res;
        vector<int> re;
        vector<int> visited(nums.size(),0);
        helper(nums, res, re, visited);
        return res;
    }
};

Permutations II

"""改改。
if (i > 0 && nums[i] == nums[i - 1] && visited[i - 1] == 0) continue; //这行配合sort才行
"""
class Solution {
public:
    void helper(vector<int>& nums,  vector<vector<int>>& res, vector<int>& re, vector<int>& visited){
        if(re.size() == nums.size())
            res.push_back(re);
        else
            for(int i=0;i<nums.size();i++){
                if(!visited[i]){
                    if (i > 0 && nums[i] == nums[i - 1] && visited[i - 1] == 0) continue; //
                    visited[i] = 1;
                    re.push_back(nums[i]);
                    helper(nums, res, re, visited);
                    re.pop_back();
                    visited[i] = 0;
                }
            }
    }
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        if(nums.empty())
            return {};
        sort(nums.begin(), nums.end());
        vector<vector<int>> res;
        vector<int> re;
        vector<int> visited(nums.size(),0);
        helper(nums, res, re, visited);
        return res;
    }
};

Rotate Image

class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        int n = matrix.size();
        for(int i=0;i<n;i++)
            for(int j=i;j<n;j++)
                swap(matrix[i][j], matrix[j][i]);

        for(int i=0;i<n;i++)
            for(int j=0; j<n/2;j++)
                swap(matrix[i][j], matrix[i][n-j-1]);
    }
};

Group Anagrams

"""注意时空复杂度分析
"""
class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        vector<vector<string>> res;
        unordered_map<string, vector<string>> m;
        int count[26] = {0};
        for(string s : strs){
            memset(count, 0, sizeof(count));
            for(char c : s)
                count[c-'a'] ++;
            string encoding = "";
            for(int n:count){
                encoding += to_string(n);
                encoding += 'c';
            }

            m[encoding].push_back(s);
        }

        for(auto i : m)
            res.push_back(i.second);
        return res;
    }
};

Pow(x, n)

"""需要考虑时间和越界
"""
class Solution {
public:
    double myPow(double x, int n) {
        if(n==0)
            return 1;
        if(n==1)
            return x;
        if(n==-1)
            return 1/x;

        double y;
        if(n%2==0){
            y = myPow(x,n/2);
            y *= y;
        }
        else{
            y = myPow(x,(n-1)/2);
            y *= y;
            y *= x;
        }
        return y;
    }
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

LeetCode: 16 回溯 的相关文章

  • 五大常用经典算法

    五大常用算法之一 分治算法 一 基本概念 在计算机科学中 分治法是一种很重要的算法 字面上的解释是 分而治之 就是把一个复杂的问题分成两个或更多的相同或相似的子问题 再把子问题分成更小的子问题 直到最后子问题可以简单的直接求解 原问题的解即
  • 50个c/c++源代码网站

    C C 是最主要的编程语言 这里列出了50名优秀网站和网页清单 这些网站提供c c 源代码 这份清单提供了源代码的链接以及它们的小说明 我已尽力包括最佳的C C 源代码的网站 这不是一个完整的清单 您有建议可以联系我 我将欢迎您的建 议 以
  • netty handler的执行顺序(3)

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 今天解决2个问题 1 handler在pipeline当中究竟是如何存储的 2 在遍历handler的过程中 会根据event的不同 调用不同的handler 这一点是如何
  • BP神经网络与Python实现

    人工神经网络是一种经典的机器学习模型 随着深度学习的发展神经网络模型日益完善 联想大家熟悉的回归问题 神经网络模型实际上是根据训练样本创造出一个多维输入多维输出的函数 并使用该函数进行预测 网络的训练过程即为调节该函数参数提高预测精度的过程
  • LeetCode83: 删除排序链表中的重复元素

    给定一个已排序的链表的头 head 删除所有重复的元素 使每个元素只出现一次 返回 已排序的链表 示例 1 输入 head 1 1 2 输出 1 2 示例 2 输入 head 1 1 2 3 3 输出 1 2 3 提示 链表中节点数目在范围
  • 直线检测方法—LSD论文翻译

    附原文链接 LSD a Line Segment Detector 摘 要 LSD是一个线段检测器 能够在线性时间内得到亚像素级精度的检测结果 它无需调试参数就可以适用于任何数字图像上 并且能够自我控制错误数量的检测 平均来说 一个图像中允
  • Qt——用于表格QTableView的模型

    如果想使用表格来呈现数据 Qt提供了一个方便的部件QTableWidget 但是直接用它实现一些功能可能比较困难 这里将介绍一种强大 灵活的方式来操作表格 一 模型 视图架构 在这个架构中 模型用于存储数据 视图用于呈现数据 除此之外 还有
  • 数据结构----链式栈

    目录 前言 链式栈 操作方式 1 存储结构 2 初始化 3 创建节点 4 判断是否满栈 5 判断是否空栈 6 入栈 7 出栈 8 获取栈顶元素 9 遍历栈 10 清空栈 完整代码 前言 前面我们学习过了数组栈的相关方法 链接 线性表 栈 栈
  • findBug 错误修改指南

    FindBugs错误修改指南 1 EC UNRELATED TYPES Bug Call to equals comparing different types Pattern id EC UNRELATED TYPES type EC c
  • 常用的十种算法--马踏棋盘算法

    1 马踏棋盘算法介绍 马踏棋盘算法也被称为骑士周游问题 将马随机放在国际象棋的 8 8 棋盘 Board 0 7 0 7 的某个方格中 马按走棋规则 马走日字 进行移动 要求每个方格只进入一次 走遍棋盘上全部 64 个方格 2 马踏棋盘算法
  • 亚利桑那州立大学周纵苇:研习 U-Net ——现有的分割网络创新

    雷锋网AI研习社按 经典的 Encoder Decoder 结构在目标分割问题中展现出了举足轻重的作用 然而这样一个相对固定的框架使得模型在感受野大小和边界分割精度两方面很难达到兼顾 本次公开课 讲者以 U Net 为案例分析 总结现有的分
  • 如何根据链表节点数据大小对链表节点进行排序

    对链表排序有两种方法 1 比较了两个节点的大小后 对指针进行改变 从而交换节点的顺序 2 比较了两个节点的大小后 只交换数据域 而不改变指针 从而交换节点的顺序 第二种办法比较简单 本文主要对第二种方法进行讲解 链表节点排序算法 采用 冒泡
  • UE4命令行使用,解释

    命令行在外部 从命令行运行编辑项目 1 导航到您的 LauncherInstall VersionNumber Engine Binaries Win64 目录中 2 右键单击上 UE4Editor exe 的可执行文件 并选择创建快捷方式
  • 图 - Java实现无向带权图的邻接矩阵表示法

    图 Java实现无向带权图的邻接矩阵表示法 1 图 1 1 图的介绍 图 Graph 是一种复杂的非线性表结构 图中的元素我们就叫做顶点 vertex 图中的一个顶点可以与任意其他顶点建立连接关系 我们把这种建立的关系叫做边 edge 跟顶
  • 算法学习——贪心算法之币种统计

    算法描述 币种统计 单位给每一位员工发工资 精确到元 为了保证不临时换零钱 使得每个员工取款的张数最少 在取工资前统计所有员工所需要的各种票面的张数 约定票种为100 50 20 10 5 2 1元 并验证币种统计是否正确 算法思路 算法描
  • 数据结构与算法-列表(双向链表)设计及其排序算法

    0 概述 本文主要涵盖列表 双向链表 的设计及其排序算法的总结 列表是一种典型的动态存储结构 其中的数据 分散为一系列称作节点 node 的单位 节点之间通过指针相互索引和访问 为了引入新节点或删除原有节点 只需在局部调整少量相关节点之间的
  • 查找数组中第二大的数

    快速找出一个数组中的最大数 第二大数 思路 如果当 前元素大于最大数 max 则让第二大数等于原来的最大数 max 再把当前元素的值赋给 max 如果当前的元素大于等于第二大数secondMax的值而小于最大数max的值 则要把当前元素的值
  • 按照层次遍历结果打印完全二叉树

    按照层次遍历结果打印完全二叉树 按照推论结果 l 层首个节点位置 2 h l 1 l 层节点间距 2 h l 1 1 编码实现 public static
  • 从源码角度来谈谈 HashMap

    HashMap的知识点可以说在面试中经常被问到 是Java中比较常见的一种数据结构 所以这一篇就通过源码来深入理解下HashMap 1 HashMap的底层是如何实现的 基于JDK8 1 1 HashMap的类结构和成员 HashMap继承
  • 浅谈归并排序:合并 K 个升序链表的归并解法

    在面试中遇到了这道题 如何实现多个升序链表的合并 这是 LeetCode 上的一道原题 题目具体如下 用归并实现合并 K 个升序链表 LeetCode 23 合并K个升序链表 给你一个链表数组 每个链表都已经按升序排列 请你将所有链表合并到

随机推荐

  • Arduino控制舵机

    一 舵机一般有三根线 和Arduino连接一般如下 二 代码分析 include
  • 为什么我们使用Story Points进行估算?

    故事点 Story Points 简介 Scrum指南告诉我们 估算应该由将要完成工作的人提供 但它并没有告诉我们应该如何提供估算 它把这个决定留给了我们 Scrum团队使用的一种常见策略是使用称为故事点的度量单位进行估算 但为什么要使用S
  • hive的row_number()、rank()和dense_rank()的区别以及具体使用

    row number rank 和dense rank 这三个是hive内置的分析函数 下面我们来看看他们的区别和具体的使用案例 首先创建一个文件test A 1 B 3 C 2 D 3 E 4 F 5 G 6 1 2 3 4 5 6 7
  • 国际化字符编码处理总结

    在处理国际化时 处理不当就会产生乱码 通用的做法是都转换为UTF 8编码 对于高层开发语言十分简单 对于底层编程语言则有些复杂 其中涉及的概念也有很多 字符是指计算机中使用的字母 数字 字和符号 包括 1 2 3 A B C 等等 在 AS
  • ‘‘‘python‘‘‘内置函数

    目录 关键字 class 定义类 内置函数 和定义函数的调用一致 常用方法 字符串的方法
  • lua/luci入门

    lua 注释 单行注释 多行注释 数据类型可以用type函数判断 nil 未使用过的变量 既是值 也是类型 boolean string number 相当于c里的double table 唯一的数据结构 基本与php数组类型同 索引数组从
  • openwrt之Uci

    Openwrt中所有的配置文件都存放再 etc config中 uci是openwrt中用来修改配置文件的一个软件 一 配置文件的格式 config声明一个section example 指的是section的type 也就是类型 test
  • C++ 多语言切换

    如果设置UI资源文件非重点不做介绍 设置英文版接口 SetThreadUILanguage MAKELANGID LANG ENGLISH SUBLANG ENGLISH US 此时如果操作系统的语言选择的是简体中文 那么掉系统的AfxMe
  • 已解决(Python3中pip无法安装urllib报错问题)No matching distribution found for urllib

    已解决 Python3中pip无法安装urllib报错问题 ERROR Could not find a version that satisfies the requirement urllib from versions none ER
  • selenium 下载文件取消安全下载的配置

    使用 selenium 下载碰见的问题 文件存在危险 因此 Chrome 已将其拦截 查找了很多配置文件都无法解决这个问题 经过多次测试 下面的参数配置可以解决这个问题 selenium 下载文件取消安全下载的配置 如果想要下载文件 可以添
  • MATLAB/Simulink 永磁同步电机启动(I/F控制) 中高速运行(滑模观测器控制/磁链观测器)

    MATLAB Simulink 永磁同步电机启动 I F控制 中高速运行 滑模观测器控制 磁链观测器 运行模式间切换方案设计 性能要求 价格等方面请加好友 卡尔曼滤波器加锁相环 ID 1628564485704566696Elaine
  • java jen部署_CSS布局:Jen Simmons的网格,区域和@Supports

    java jen部署 In this episode of the Versioning Show Tim and David are joined by Jen Simmons Designer Advocate at Mozilla a
  • Python3 基础语法练习小Demo

    文章目录 反恐精英基础版 分析 代码实现 反恐精英修复版 分析 代码实现 反恐精英加强版 分析 代码实现 反恐精英超级加强版 分析 代码实现 反恐精英基础版 一个精英对一个匪徒 分析 定义人类 描述公共属性 life 100 name 姓名
  • 自定义开发成绩查询小程序

    在当今数字化时代 教育行业借助技术手段提高教学效果 作为老师 拥有一个自己的成绩查询系统可以帮助你更好地管理学生成绩 并提供更及时的反馈 本文将为你详细介绍如何从零开始搭建一个成绩查询系统 让你的教学工作更加高效和便捷 不过比较便捷好用的方
  • [人工智能-深度学习-44]:开发环境 - Anaconda的目录结构与SourceInsight工程

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 https blog csdn net HiWangWenBing article details 121309970 目录 第1章 前言
  • 如何在Ubuntu系统中使用Traefik为容器设置反向代理?

    Traefik 是一种为 docker 容器建立反向代理的现代方法 当您希望在 docker 容器中运行多个应用程序 并公开端口 80 和 443 时 traefik 可能是反向代理的最佳选择 Traefik 提供了自己的监控仪表板 您还可
  • Visual Studio Code输出窗口中文乱码

    Visual Studio Code输出窗口中文乱码 Visual Studio Code输出窗口中文乱码 为了防止自己以后又忘记 只能自己写文章记下来 区别VS Code和VS 1 vs2019是个IDE vscode本质上是个编辑器 只
  • cuda核函数传入__device__函数指针的使用例子

    cuda的global函数里面可以调用 device 函数 在有特殊需要的时候 还可以把 device 函数作为参数传入到一个 global 函数中 在cuda里面不能像c 那样简单地传入函数的指针 需要在传入前对函数的指针做一些包装 例如
  • Qt 改变形状的对话框

    ifndef SORTDIALOG H define SORTDIALOG H include
  • LeetCode: 16 回溯

    Letter Combinations of a Phone Number 这种题就是DFS 递归 一堆传引用 迭代解法见http www cnblogs com grandyang p 4452220 html 也可以用队列实现 clas