力扣题目训练(17)

这篇具有很好参考价值的文章主要介绍了力扣题目训练(17)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

2024年2月10日力扣题目训练

2024年2月10日第十七天编程训练,今天主要是进行一些题训练,包括简单题3道、中等题2道和困难题1道。惰性太强现在才完成,不过之后我会认真完成的。

551. 学生出勤记录 I

链接: 出勤记录
难度: 简单
题目:
力扣题目训练(17),编程学习,leetcode,算法,c++

运行示例:
力扣题目训练(17),编程学习,leetcode,算法,c++

思路:
这道题就是一个简单的遍历,只需在遍历时判断是否不符合条件的情况即可。
代码:

class Solution {
public:
    bool checkRecord(string s) {
        int re1 = 0;
        int re2 = 0;
        for(int i = 0; i < s.size(); i++){
            if(s[i] == 'A'){
                re1++;
                re2 = 0;
                if(re1 == 2) return false;
            }else if(s[i] == 'L'){
                re2++;
                if(re2 == 3) return false;
            }else{
                re2 = 0;
            }
        }
        return true;
    }
};

557. 反转字符串中的单词 III

链接: 反转字符串中的单词
难度: 简单
题目:
力扣题目训练(17),编程学习,leetcode,算法,c++

运行示例:
力扣题目训练(17),编程学习,leetcode,算法,c++

思路:
这道题主要是遍历找到空格,根据空格将单词进行反转。
代码:

class Solution {
public:
    string reverseWords(string s) {
        int left = 0;
        string ans;
        for(int i = 0; i < s.size(); i++){
            if(s[i] == ' '){
                string tmp = s.substr(left,i-left);
                cout<<"asdf:"<<tmp<<endl;
                reverse(tmp.begin(),tmp.end());
                ans += tmp;
                ans += ' ';
                left = i+1;
            }
        }
        if(left != s.size()){
            string tmp = s.substr(left,s.size()-left);
            reverse(tmp.begin(),tmp.end());
            ans += tmp;
        }
        return ans;
    }
};

559. N 叉树的最大深度

链接: N 叉树的最大深度
难度: 简单
题目:
力扣题目训练(17),编程学习,leetcode,算法,c++

运行示例:
力扣题目训练(17),编程学习,leetcode,算法,c++

思路:
这道题求N叉树的深度,与543. 二叉树的直径类似,只是从二叉树拓展到N叉树而已。大家也可以先写一下104. 二叉树的最大深度添加链接描述和543. 二叉树的直径进行锻炼之后再写这道题。
代码:

class Solution {
public:
    int maxDepth(Node* root) {
        if(root == NULL) return 0;
        int maxChildDepth = 0;
        vector<Node*> children = root->children;
        for(int i = 0; i < children.size(); i++){
            int childrenDepth = maxDepth(children[i]);
            maxChildDepth = max(maxChildDepth,childrenDepth);
        }
        return maxChildDepth+1;
    }
};

241. 为运算表达式设计优先级

链接: 优先级
难度: 中等
题目:
力扣题目训练(17),编程学习,leetcode,算法,c++

运行示例:
力扣题目训练(17),编程学习,leetcode,算法,c++

思路:
这道题核心就是分治,利用运算符进行分割,递归求解结果。遍历字符串,每次遇到运算符时,将字符串分为运算符左侧和运算符右侧两部分,递归求解这两部分的结果。此外为避免重复计算我们可以利用一个哈希表记录已经计算过的部分。
代码:

class Solution {
public:
    unordered_map<string,vector<int>> memo;
    vector<int> findsome(string s){
        if(memo.find(s) != memo.end()) return memo[s];
        vector<int> ans;
        for(int i = 0; i <s.size(); i++){
            if(!isdigit(s[i])){
                vector<int> ans1 = findsome(s.substr(0,i));
                vector<int> ans2 = findsome(s.substr(i+1));
                if(s[i] == '+'){
                    for(auto& x: ans1)
                        for(auto& y: ans2) ans.push_back(x+y);
                }else if(s[i] == '-')
                    for(auto& x: ans1)
                        for(auto& y: ans2) ans.push_back(x - y);
                
                else
                    for(auto& x: ans1)
                        for(auto& y: ans2) ans.push_back(x * y);
            }
        }
        if(ans.empty()) ans.push_back(stoi(s));
        memo[s] = ans;
        return ans;
    }
    vector<int> diffWaysToCompute(string expression) {
        return findsome(expression);
    }
};

260. 只出现一次的数字 III

链接: 只出现一次的数字
难度: 中等
题目:
力扣题目训练(17),编程学习,leetcode,算法,c++

运行示例:
力扣题目训练(17),编程学习,leetcode,算法,c++

思路:
这道题考虑位运算,我们知道异或运算有以下性质:
任何数和 0做异或运算,结果仍然是原来的数,即 x⊕0=x;
任何数和其自身做异或运算,结果是 0,即 x⊕x=0;

根据这条性质,我们将数组中的所有数字进行异或运算,得到的结果即为两个只出现一次的数字的异或结果。但由于这两个数字不相等,因此异或结果中至少存在一位为 1。我们可以通过 lowbit 运算找到异或结果中最低位的 1,并将数组中的所有数字按照该位是否为 1分为两组,这样两个只出现一次的数字就被分到了不同的组中。 从而得到结果。

代码:文章来源地址https://www.toymoban.com/news/detail-831549.html

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
        long long sum = 0;
        for(auto& num:nums) sum ^= num;
        int lsb = sum &(-sum);
        int a = 0,b = 0;
        for (auto& num: nums) {
            if (num & lsb) {
                a ^= num;
            }
            else {
                b ^= num;
            }
        }
        return {a,b};
    }
};

126. 单词接龙 II

链接: 单词接龙
难度: 困难
题目:
力扣题目训练(17),编程学习,leetcode,算法,c++

运行示例:
力扣题目训练(17),编程学习,leetcode,算法,c++

思路:
这道题我知道是应该用递归和回溯,但是不知道如何动笔。官方是利用广度优先搜索 + 回溯,建立图。
本题要求的是最短转换序列,看到最短首先想到的就是广度优先搜索。但是本题没有给出显示的图结构,根据单词转换规则:把每个单词都抽象为一个顶点,如果两个单词可以只改变一个字母进行转换,那么说明它们之间有一条双向边。因此我们只需要把满足转换条件的点相连,就形成了一张图。根据示例 1 中的输入,我们可以建出下图:

力扣题目训练(17),编程学习,leetcode,算法,c++
基于该图,我们以 “hit"为图的起点, 以 “cog"为终点进行广度优先搜索,寻找 “hit"到 “cog"的最短路径。下图即为答案中的一条路径。
力扣题目训练(17),编程学习,leetcode,算法,c++
由于要求输出所有的最短路径,因此我们需要记录遍历路径,然后通过回溯得到所有的最短路径。

细节

  • 从一个单词出发,修改每一位字符,将它修改成为 ‘a’到 ‘z’中的所有字符,看看修改以后是不是在题目中给出的单词列表中;
  • 有一些边的关系,由于不是最短路径上的边,不可以被记录下来。为此,我们为扩展出的单词记录附加的属性:层数。即下面代码中的steps。如果当前的单词扩散出去得到的单词的层数在以前出现过,则不应该记录这样的边的关系。

代码:

class Solution {
public:
    vector<vector<string>> findLadders(string beginWord, string endWord, vector<string> &wordList) {
        vector<vector<string>> res;
        // 因为需要快速判断扩展出的单词是否在 wordList 里,因此需要将 wordList 存入哈希表,这里命名为「字典」
        unordered_set<string> dict = {wordList.begin(), wordList.end()};
        // 修改以后看一下,如果根本就不在 dict 里面,跳过
        if (dict.find(endWord) == dict.end()) {
            return res;
        }
        // 特殊用例处理
        dict.erase(beginWord);

        // 第 1 步:广度优先搜索建图
        // 记录扩展出的单词是在第几次扩展的时候得到的,key:单词,value:在广度优先搜索的第几层
        unordered_map<string, int> steps = {{beginWord, 0}};
        // 记录了单词是从哪些单词扩展而来,key:单词,value:单词列表,这些单词可以变换到 key ,它们是一对多关系
        unordered_map<string, set<string>> from = {{beginWord, {}}};
        int step = 0;
        bool found = false;
        queue<string> q = queue<string>{{beginWord}};
        int wordLen = beginWord.length();
        while (!q.empty()) {
            step++;
            int size = q.size();
            for (int i = 0; i < size; i++) {
                const string currWord = move(q.front());
                string nextWord = currWord;
                q.pop();
                // 将每一位替换成 26 个小写英文字母
                for (int j = 0; j < wordLen; ++j) {
                    const char origin = nextWord[j];
                    for (char c = 'a'; c <= 'z'; ++c) {
                        nextWord[j] = c;
                        if (steps[nextWord] == step) {
                            from[nextWord].insert(currWord);
                        }
                        if (dict.find(nextWord) == dict.end()) {
                            continue;
                        }
                        // 如果从一个单词扩展出来的单词以前遍历过,距离一定更远,为了避免搜索到已经遍历到,且距离更远的单词,需要将它从 dict 中删除
                        dict.erase(nextWord);
                        // 这一层扩展出的单词进入队列
                        q.push(nextWord);
                        // 记录 nextWord 从 currWord 而来
                        from[nextWord].insert(currWord);
                        // 记录 nextWord 的 step
                        steps[nextWord] = step;
                        if (nextWord == endWord) {
                            found = true;
                        }
                    }
                    nextWord[j] = origin;
                }
            }
            if (found) {
                break;
            }
        }
        // 第 2 步:回溯找到所有解,从 endWord 恢复到 beginWord ,所以每次尝试操作 path 列表的头部
        if (found) {
            vector<string> Path = {endWord};
            backtrack(res, endWord, from, Path);
        }
        return res;
    }

    void backtrack(vector<vector<string>> &res, const string &Node, unordered_map<string, set<string>> &from,
             vector<string> &path) {
        if (from[Node].empty()) {
            res.push_back({path.rbegin(), path.rend()});
            return;
        }
        for (const string &Parent: from[Node]) {
            path.push_back(Parent);
            backtrack(res, Parent, from, path);
            path.pop_back();
        }
    }
};

到了这里,关于力扣题目训练(17)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 算法学习——LeetCode力扣回溯篇2

    40. 组合总和 II - 力扣(LeetCode) 描述 给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的每个数字在每个组合中只能使用 一次 。 注意:解集不能包含重复的组合。 示例 示例 1: 输入: candidates = [10,1,2,7

    2024年02月20日
    浏览(35)
  • 算法学习——LeetCode力扣字符串篇

    344. 反转字符串 - 力扣(LeetCode) 描述 编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。 示例 示例 1: 输入:s = [“h”,“e”,“l”

    2024年02月20日
    浏览(44)
  • 【leetcode 力扣刷题】回文串相关题目(KMP、动态规划)

    题目链接:5. 最长回文子串 题目内容: 题目就是要我们找s中的回文子串,还要是最长的。其实想想,暴力求解也行……就是遍历所有的子串,同时判断是不是回文串,是的话再和记录的最大长度maxlen比较,如果更长就更新。时间复杂度直接变成O(n^3)。 优化的点在于,假设子

    2024年02月09日
    浏览(48)
  • 编程 100个训练题目

    编程题: 1.输入一串字符,分别统计元音字母和其他字母的个数,并显示统计结果,不区分字母大小写。 2.输入三角形三条边 a,b,c 的值,根据其数据,判断能否构成三角形。若能构成三角形,还要 显示三角形的性质:等边三角形、等腰三角形、直角三角形、任意三角形。 3.输入

    2024年02月12日
    浏览(45)
  • 【LeetCode力扣】面试题 17.14. 最小K个数(top-k问题)

    目录 1、题目介绍 2、解题思路 2.1、优先队列解法 2.2、top-k问题解法 原题链接: 面试题 17.14. 最小K个数 - 力扣(LeetCode)  题目要求非常简短,也非常简单,就是求一组数中的k个最小数。         如果在正常刷题过程中遇到这种题,那么这道题毋庸置疑是秒杀题,使用最

    2024年01月25日
    浏览(41)
  • 算法学习——LeetCode力扣图论篇3(127. 单词接龙、463. 岛屿的周长、684. 冗余连接、685. 冗余连接 II)

    127. 单词接龙 - 力扣(LeetCode) 描述 字典 wordList 中从单词 beginWord 和 endWord 的 转换序列 是一个按下述规格形成的序列 beginWord - s1 - s2 - … - sk: 每一对相邻的单词只差一个字母。 对于 1 = i = k 时,每个 si 都在 wordList 中。注意, beginWord 不需要在 wordList 中。 sk == endWord 给你两

    2024年04月09日
    浏览(77)
  • (C语言版)力扣(LeetCode)面试题 17.04. 消失的数字5种解法

    该题目取自力扣(LeetCode)面试题 17.04. 消失的数字 链接:消失的数字 该题目主要考察时间复杂度的把握,题目如下: 数组nums包含从0到n的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗? 注意:本题相对书上原题稍作改动 示例

    2023年04月14日
    浏览(40)
  • 力扣算法-Day17

    给你一个整数数组  nums  ,判断是否存在三元组  [nums[i], nums[j], nums[k]]  满足  i != j 、 i != k  且  j != k  ,同时还满足  nums[i] + nums[j] + nums[k] == 0  。请  你返回所有和为  0  且不重复的三元组。 注意: 答案中不可以包含重复的三元组。 思路: 双指针:首先要将nums数组

    2024年01月24日
    浏览(45)
  • 算法学习——LeetCode力扣补充篇11(64. 最小路径和、48. 旋转图像 、169. 多数元素、394. 字符串解码、240. 搜索二维矩阵 II )

    64. 最小路径和 - 力扣(LeetCode) 描述 给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。 说明:每次只能向下或者向右移动一步。 示例 示例 1: 输入:grid = [[1,3,1],[1,5,1],[4,2,1]] 输出:7 解释:因为路径 1→3→1→

    2024年04月23日
    浏览(38)
  • 力扣题目学习笔记(OC + Swift)24. 两两交换链表中的节点

    给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。 首先定义递归终止条件: head.next不存,代表链表结束了 head.next.next不存在,表示不能两两配对 Swift OC 用到了解决链表问题的

    2024年02月04日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包