【LeetCode题解】2645. 构造有效字符串的最少插入数(计算组数+动态规划+考虑相邻字母)+2085. 统计出现过一次的公共字符串(哈希表)+2807. 在链表中插入最大公约数

这篇具有很好参考价值的文章主要介绍了【LeetCode题解】2645. 构造有效字符串的最少插入数(计算组数+动态规划+考虑相邻字母)+2085. 统计出现过一次的公共字符串(哈希表)+2807. 在链表中插入最大公约数。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

2645. 构造有效字符串的最少插入数

【LeetCode题解】2645. 构造有效字符串的最少插入数(计算组数+动态规划+考虑相邻字母)+2085. 统计出现过一次的公共字符串(哈希表)+2807. 在链表中插入最大公约数,LeetCode,leetcode,动态规划,散列表

方法一:计算组数

1.用count统计,能构成几组abc

2.如果当前字符大于之前字符,说明还在组内,不更新

3.如果当前字符小于等于之前字符,说明不是同一组的abc,组数更新

4.最终返回值:组数*3,再减去原本的字符数,就是要插入的次数

    //2645. 构造有效字符串的最少插入数---计算组数
    public int addMinimum2(String word) {
        int n = word.length();
        int count = 1;
        //最终构成abc的组数
        for (int i = 1; i < n; i++) {
            if (word.charAt(i - 1) >= word.charAt(i)) {
                //当前字符小于等于之前字符
                count++;
                //组数加一
            }
        }
        return count*3-n;
        //返回最终构成abc的总数-原本字符,即为要插入的次数
    }
方法二:动态规划

1.从1开始,d[i]为前i个字符拼成abc需要的最小插入数

2.情况一:word[i]单独存在于一组abc中,需要插两次,才能组成abc.插入次数为之前的次数+2

3.情况二:当前字符比前一个字符大,需要插一次,就可以组成abc.修改当前插入次数为:之前的次数-1,因为之前插入的两次中已经包含了当前字符。

    public int addMinimum(String word) {
        int n = word.length();
        int[] d = new int[n + 1];
        //d[]数组用来统计,1到n的插入次数
        //从1开始,d[i]为前i个字符拼成abc需要的最小插入数。
        for (int i = 1; i <= n; i++) {
            d[i] = d[i - 1] + 2;
            //word[i]单独存在于一组abc中,在之前情况的基础上+2. eg: a+bc / b+ac / c+ab
            if (i > 1 && word.charAt(i - 1) > word.charAt(i - 2)) {
                //如果当前字符比前一个字符大,eg:ab/ ac / bc
                d[i] = d[i - 1] - 1;
                //当前字符和之前的字符在同一个abc中,重新覆盖d[i],前一个位置的插入数-1
            }
        }
        return d[n];
    }

方法三: 考虑相邻字母

1.设当前字符为x,前一个字符为y,

2.x大于y的情况:x-y-1

3.x小于等于y的情况:(x-y-1+3)mod 3 ,将计算的结果控制在0-2之间

4.开头的单独一个字符:word[0]-‘a’ ,结尾的一个字符:‘c’-word[n-1],合并为word[0]-word[n-1]+2

    public int addMinimum3(String word) {
        int n = word.length();
        int res = word.charAt(0) - word.charAt(n - 1) + 2;
        //合并处理开头和结尾的情况
        for (int i = 1; i < n; i++) {
            res += (word.charAt(i) - word.charAt(i - 1) + 2) % 3;
        }
        return res;
    }

1-11 生日快乐

2085. 统计出现过一次的公共字符串

【LeetCode题解】2645. 构造有效字符串的最少插入数(计算组数+动态规划+考虑相邻字母)+2085. 统计出现过一次的公共字符串(哈希表)+2807. 在链表中插入最大公约数,LeetCode,leetcode,动态规划,散列表

思路:哈希表计算

1.用两个哈希表分别统计word1和word2中字符出现的次数

2.遍历words1中的每个单词x,并使用count1.put(x,count1.getOrDefault(x,0)+1)将单词x作为键,将其在count1中对应的值加1存储起来,count1.getOrDefault(x,0)表示获取count1中键为x的值,如果不存在则返回默认值0。

3.同理遍历word2,同样操作

4.遍历count1的键集合count1.keySet(),对于每个键x,判断count1.get(x)是否等于1且count2.getOrDefault(x,0)是否等于1。如果满足条件,则将res加1。

    public int countWords(String[] words1, String[] words2) {
        Map<String,Integer> count1 = new HashMap<>();
        Map<String,Integer> count2 = new HashMap<>();
        //存储每个单词在对应数组中出现的次数
        for (String x:
             words1 ) {
            // 遍历第一个字符串数组words1,将单词及其出现次数存储到count1中
            count1.put(x,count1.getOrDefault(x,0)+1);
        }
        for (String x:
                words2 ) {
            // 遍历第二个字符串数组words2,将单词及其出现次数存储到count2中
            count2.put(x,count2.getOrDefault(x,0)+1);
        }
        int res = 0;
        //记录相同单词的数量
        for (String x:
             count1.keySet()) {
            // 遍历count1的键集合,判断在count1中出现次数为1且在count2中也出现次数为1的单词
            if (count1.get(x)==1&&count2.getOrDefault(x,0)==1){
                res++;
            }
        }
        return res;
    }

2807. 在链表中插入最大公约数

【LeetCode题解】2645. 构造有效字符串的最少插入数(计算组数+动态规划+考虑相邻字母)+2085. 统计出现过一次的公共字符串(哈希表)+2807. 在链表中插入最大公约数,LeetCode,leetcode,动态规划,散列表

思路:模拟

1.调用函数求出要插入的最大公约数

2.插入到cur的后面

3.因为插了一位,所以移动两个位置


    public ListNode insertGreatestCommonDivisors(ListNode head) {
        ListNode cur = head;
        while (cur.next!=null){
            int gcdVal = gcd(cur.val,cur.next.val);
            //调用函数求出要插入的最大公约数
            cur.next = new ListNode(gcdVal,cur.next);
            //插入到cur的后面
            cur = cur.next.next;
            //因为插了一位,所以移动两个位置
        }
        return head;
    }

    /**
     * 求两个结点值的最大公约数
     * @param a
     * @param b
     * @return
     */
    private int gcd(int a,int b){
        //求最大公约数有多种写法
        while (a!=0){
            int temp = a;
            a = b % a;
            b = temp;
        }
        return b;
    }

求最大公约数的几种方法:

1.暴力枚举法

    public static int gcd(int a, int b) {
        int min = a < b ? a : b;//判断并取出两个数中小的数
        for (int i = min; i >= 1; i--) { //循环,从最小值开始,依次递减,直到i=1
            if (a%i==0&&b%i==0){    //当i能同时被A和B余尽时,返回i
                return i;
            }
        }
        return 0;
    }

}

2.辗转相除法

 public static int gcd(int a, int b) {// 辗转相除法
        int c = a % b;   //先将a对b取余
        while (c != 0) {   //当余数不等于0时,一直进行循环,直到余数等于0,公约数就为b
            a = b;         //将a对b的余数再对b取余,直到循环结束
            b = c;
            c = a % b;
        }
        return b;
    }

3.辗转相除法 —递归调用

    public static int gcd(int a, int b) {// 辗转相除法 改进,调用函数递归
        int max = a > b ? a : b; //求出大的数
        int min = a < b ? a : b; //求出小的数
        if(max%min==0){
            return min;      //当大数模小数能余尽时,最大公约数就是小的数
        }
        return gcd(max%min,min);//递归函数,参数去前两个数的余数,和小的数

4.辗转相除法 —递归调用—简化写法

public static int gcd(int a, int b) {// 辗转相除法 改进,调用函数递归
        return (a % b == 0) ? b : gcd(b, a%b );// 相同思路,三元运算/简化写法
    }

1.如果a余b等于0,说明b就是最大公约数

2.否则,进行递归,b代替曾经的a,让a%b产生的余数代替曾经的b。

3.始终确保大数%小数

4.即使b位置上是值大于a, b代替a后,a(小数)%b(大数) = a ,相当于替换位置

  1. (b,a%b)的位置不能交换,否则无法跳出递归

5.调用函数递归 更相减损法

 public static int gcd(int a, int b) {//调用函数递归 更相减损法
        int max = a>b?a:b;
        int min = a<b?a:b;
        if(max%min==0){
            return min;
        }
        return gcd(max-min,min);//相同思路,将%改为-,优化速度
    }

6.调用函数递归 更相减损法–简化

    public static int gcd(int a, int b) {//调用函数递归 更相减损法 简易写法
        if (a < b) {
            int tmp = a;
            a = b;
            b = tmp;
        }
        return (a % b == 0) ? b : gcd(a - b, b);
    

简化不用找大小数,把大数放到前面

因为小数减大数为负数,所以要把大数替换到前面,

    public static int gcd5(int a, int b) {//调用函数递归 更相减损法 简易写法
        return (a % b == 0) ? b : a > b ? gcd5(a - b, b) : gcd5(b-a,a);
    }

压行写法,就是三目嵌套,就是可读性不高

点击移步博客主页,欢迎光临~

【LeetCode题解】2645. 构造有效字符串的最少插入数(计算组数+动态规划+考虑相邻字母)+2085. 统计出现过一次的公共字符串(哈希表)+2807. 在链表中插入最大公约数,LeetCode,leetcode,动态规划,散列表文章来源地址https://www.toymoban.com/news/detail-848502.html

到了这里,关于【LeetCode题解】2645. 构造有效字符串的最少插入数(计算组数+动态规划+考虑相邻字母)+2085. 统计出现过一次的公共字符串(哈希表)+2807. 在链表中插入最大公约数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • leetcode-2645 构造有效字符串的最小插入数

    题目链接 2645. 构造有效字符串的最少插入数 - 力扣(LeetCode) 解题思路 动态规划 1、定义状态d[i]为将前i个字符(为了方便编码,下标从1开始)拼凑成若干个abc所需要的最小插入数。那么初始状态d[0]=0,最终要求解d[n],其中n为word的长度。 2、转移过程 3、因为每个字符都尽

    2024年02月02日
    浏览(34)
  • 【力扣·每日一题】2645. 构造有效字符串的最小插入数(动态规划 贪心 滚动数组优化 C++ Go)

    题目链接 给你一个字符串 word ,你可以向其中任何位置插入 “a”、“b” 或 “c” 任意次,返回使 word 有效 需要插入的最少字母数。 如果字符串可以由 “abc” 串联多次得到,则认为该字符串 有效 。 提示: 1 = w o r d . l e n g t h = 50 1 = word.length = 50 1 = w or d . l e n g t h = 50 w

    2024年01月16日
    浏览(37)
  • 算法第十七天-构造有效字符串的最少插入数

    考虑abc的个数 假设答案有n个\\\"abc\\\"组成,那么需要插入的字符个数为 3 ∗ n − l e n ( s ) 3*n - len(s) 3 ∗ n − l e n ( s ) 。 对于相邻的两个字符x和y(x在y左侧): 如果 x y xy x y ,那么x和y可以在同一个\\\"abc\\\"内,否则一定不在; 如果 x ≥ y xge y x ≥ y ,那么x和y一定不可以在同一个

    2024年01月17日
    浏览(33)
  • Leetcode 第 108 场双周赛 Problem C 将字符串分割为最少的美丽子字符串(动态规划)

    Leetcode 第 108 场双周赛 Problem C 将字符串分割为最少的美丽子字符串(动态规划) 题目 给你一个二进制字符串 s ,你需要将字符串分割成一个或者多个 子字符串 ,使每个子字符串都是 美丽 的。 如果一个字符串满足以下条件,我们称它是 美丽 的: 它不包含前导 0 。 它是

    2024年02月15日
    浏览(32)
  • 【算法|动态规划No.28】leetcode1312. 让字符串成为回文串的最少插入次数

    个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 🍔本专栏旨在提高自己算法能力的同时,记录一下自己的学习过程,希望对大家有所帮助 🍓希望我们一起努力、成长,共同进步。

    2024年02月06日
    浏览(44)
  • Leetcode 678. 有效的括号字符串

    有效的括号字符串 【问题描述】 给你一个只包含三种字符的字符串,支持的字符类型分别是 ‘(’、‘)’ 和 ‘*’。请你检验这个字符串是否为有效字符串,如果是有效字符串返回 true 。 有效字符串符合如下规则: 示例 1: 输入:s = “()” 输出:true 示例 2: 输入:s = “

    2024年02月13日
    浏览(29)
  • 【LeetCode每日一题】2182. 构造限制重复的字符串

    2024-1-13 2182. 构造限制重复的字符串 思路: 按照字符出现次数从高到低的顺序进行重复,通过维护一个指针 j 来寻找下一个非零出现次数的字母。同时,利用 StringBuilder 对象可以高效地构建字符串,避免频繁的字符串拼接操作 首先,创建一个长度为26的数组 cnt ,用于统计字

    2024年01月18日
    浏览(32)
  • python/c++ Leetcode题解——2744. 最大字符串配对数目

    我们可以直接使用二重循环,枚举给定的数组 words 中的 words[i] 和 words[j] 是否可以匹配。 由于题目规定了数组 words 中包含的字符串互不相同,因此在枚举时,只要保证 ij,那么每个字符串最多匹配一次。 C++: python:

    2024年01月17日
    浏览(37)
  • 数据结构与算法之字符串: Leetcode 20. 有效的括号 (Typescript版)

    有效的括号 https://leetcode.cn/problems/valid-parentheses/ 描述 给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。 有效字符串需满足: 左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。 每个右括号都有一个对应的相

    2024年02月01日
    浏览(37)
  • 算法训练day11Leetcode20有效的括号1047删除字符串中所有相邻重复项150逆波兰表达式求值

    https://leetcode.cn/problems/valid-parentheses/description/ https://programmercarl.com/0020.%E6%9C%89%E6%95%88%E7%9A%84%E6%8B%AC%E5%8F%B7.html 判断右括号后忘记pop 括号匹配是使用栈解决的经典问题。 如果还记得编译原理的话,编译器在 词法分析的过程中处理括号、花括号等这个符号的逻辑,也是使用了栈

    2024年01月17日
    浏览(49)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包