• Leetcode1071. 字符串的最大公因子(三种方法,带详细解析)


    🎶Leetcode1071. 字符串的最大公因子

    对于字符串 s 和 t,只有在 s = t + … + t(t 自身连接 1 次或多次)时,我们才认定 “t 能除尽 s”。

    给定两个字符串 str1 和 str2 。返回 最长字符串 x,要求满足 x 能除尽 str1 且 x 能除尽 str2 。


    🍧示例 1:

    输入:str1 = “ABCABC”, str2 = “ABC”
    输出:“ABC”


    🎐示例 2:

    输入:str1 = “ABABAB”, str2 = “ABAB”
    输出:“AB”

    🎡示例 3:


    输入:str1 = “LEET”, str2 = “CODE”
    输出:“”


    ❤️提示:

    1 <= str1.length, str2.length <= 1000
    str1 和 str2 由大写英文字母组成

    ✨方法一:最大公因子法

    🎊分析:

    1. 如果两个字符串有最大公因子那么str1+str2和str2+str1一定是一样的
      比如例一:str1 = “ABCABC”, str2 = “ABC” str1+str2 和 str2+str1 都是"ABCABCABC"
      如果两个字符串没有最大公因子那么str1+str2和str2+str1一定不一样
    2. 如果两个字符串有最大公因子那么str1,str2他们的长度一定符合辗转相除法,我们可以通过两个字符串的长度,计算出他们最大公因子的长度
      比如例一中str1的长度为6,str2的长度为3,6和3的最大公因数是3,输出的结果长度恰好是3
    3. 然后通过计算出来的长度使用substring()截取出来即可
    	var gcdOfStrings = function (str1, str2) {
    	    if (str1 + str2 !== str2 + str1) return '' // 如果不满足最大公因子的条件直接返回空字符串
    	    const gcd = (a, b) => (a % b == 0 ? b : gcd(b, a % b))//辗转相除法
    	    return str1.substring(0, gcd(str1.length, str2.length))
    	};
    
    • 1
    • 2
    • 3
    • 4
    • 5

    🍿运行结果

    在这里插入图片描述

    🎀方法二:暴力

    这个效率比较慢,主要是针对不满足条件的情况会比较浪费时间,当然可以在前面加一个不满足条件的直接返回空来解决这个效率慢的问题

    🎄源码版

    var gcdOfStrings = function (str1, str2) {
        let factor = str1.length > str2.length ? str2 : str1;
        while (factor.length) {
            if (
                str1.split(factor).every(e => e === '') &&
                str2.split(factor).every(e => e === '')
            ) {
                return factor;
            }
            factor = factor.slice(0, -1);
        }
        return ''
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    🎉解析版

      var gcdOfStrings = function (str1, str2) {
          let factor = str1.length > str2.length ? str2 : str1 //使用factor先存储str1和str2中的较短者
          // console.log(factor, 'factor')
          while (factor.length) {
            console.log(str1.split(factor), " str1.split(factor)")
            console.log(str2.split(factor), " str2.split(factor)")
            // 判断如果str1 和str2 都能被factor所分隔则这时的factor就是正确答案
            if (
              str1.split(factor).every(e => e === '') &&
              str2.split(factor).every(e => e === '') //split是将字符串根据传入的内容进行分隔存放到一个数组中 
              // "abc".split('b')=>['a','c']   "abbbc".split('b')=> ['a', '', '', 'c']
              // every是遍历数组中的每个元素如果都满足传入的函数的要求则返回true 否则false
            ) {
              return factor
            }
    
            factor = factor.slice(0, -1)//截取factor 每次删除factor字符串中的最后一个元素
            console.log(factor, "factor")
          }
          return '' //如果循环结束了还没有返回,则没有找到符合条件的factor 返回空字符串
        }
        console.log(gcdOfStrings("ABABAB", "ABAB"))
        console.log("abbbc".split('b'));
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    🎏运行结果

    在这里插入图片描述

    🎶方法三:暴力仿求最大公因子的辗转相除法

    🍧源码版

    var gcdOfStrings = function (str1, str2) {
        if (str1 + str2 !== str2 + str1) return ''
        return strGcb(str1, str2)
    
    }
    function strGcb(a, b) {
        return (a.split(b).every(e => e === '')) ? b : strGcb(b, a.split(b).filter(e => { if (e !== '') { return e } }).join())
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    🎐解析版

     var gcdOfStrings = function (str1, str2) {
          if (str1 + str2 !== str2 + str1) return '' //首先判断str1 str2是否有最大公因数 
          return strGcb(str1, str2)
    
        }
        function strGcb (a, b) {
          return (a.split(b).every(e => e === '')) ? b : strGcb(b, a.split(b).filter(e => { if (e !== '') { return e } }).join())
          // a % b === 0 ? b : isgy(b, a % b)  上一行代码是比着这个写出来的
    
          // a.split(b).every(e => e === ''))  这个等价于 a%b===0 
          // split是将字符串根据传入的内容进行分隔存放到一个数组中 
          // "abc".split('b')=>['a','c']   "abbbc".split('b')=> ['a', '', '', 'c']
          // every是遍历数组中的每个元素如果都满足传入的函数的要求则返回true 否则false
    
          // a.split(b).filter(e => { if (e !== '') { return e } }).join() 等价于 a % b
          // filter() 遍历数组 得到满足条件的返回值 返回一个新数组 
          // join() 将数组的每一项 用传入的值作为分隔符 拼接成一个字符串
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    🎡运行结果

    在这里插入图片描述

  • 相关阅读:
    SAP ERP系统里的那些核心主数据
    Java学习之构造器
    Vue.js+SpringBoot开发个人健康管理系统
    RabbitMQ
    性能测试工具:如何录制脚本?
    Unity-Linerenderer画线功能
    花一天时间做一个高质量飞机大战游戏,过万字Unity完整教程!漂亮学妹看了直呼666!
    JAVA基础算法(7)----- 最大连续 1 的个数( 优化版 )
    (40)Verilog实现序列10111【状态机三段式】
    ACM练习——第四天
  • 原文地址:https://blog.csdn.net/sinat_51673411/article/details/133561217