• 剥洋葱


    剥洋葱

    1. 题目信息

    输入:
        3
    输出:
        AAAAA
        ABBBA
        ABCBA
        ABBBA
        AAAAA
    注意点:
        1. 输入的数表示图形的层数
        2. 字符为A-Z, 从外到里排列
    

    2. 题目分析

    1个字母的情况:

    [
        [C]
    ]
    

    2个字母的情况:

    [
        [B, B, B],
        [B, C, B],
        [B, B, B]
    ]
    

    3个字母的情况:

    [
        [A, A, A, A, A]
        [A, B, B, B, A]
        [A, B, C, B, A]
        [A, B, B, B, A]
        [A, A, A, A, A]
    ]
    

    对于这个演变过程我们发现: 每次都是在上一层的基础上, 再累加一层数据, 我们如果用代码解决这个问题, 我们只需要按照这个逻辑即可;

    3. 代码

    const log = console.log.bind(console)
    
    const getList = (char, length) => {
        let result = []
        for (let i = 0; i < length; i++) {
            result.push(char)
        }
        return result
    }
    
    const dealCenterContent = (char, result) => {
        for (let j = 1; j < result.length - 1; j++) {
            result[j].unshift(char)
            result[j].push(char)
        }
    }
    
    const createGraphics = (number) => {
        let list = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
        let result = [[]]
    
        for (let i = number - 1; i > -1; i--) {
            let len = result[0].length
            let char = list[i]
    
            // 最开始的特殊情况
            if (i === number - 1){
                result[0][0] = char
                continue
            }
    
            let head = getList(char, len + 2)
            let end = getList(char, len + 2)
            result.unshift(head)
            result.push(end)
    
            dealCenterContent(char, result)
        }
    
        return result
    }
    
    const __main = () => {
        let number = 3
        log(createGraphics(number))
    }
    
    __main()
    

    4. 感悟

    其实这种算法题很少写思路之外的其他东西, 但是这个算法题很特殊, 其实这个算法题难度并不高, 自己很早之前就做了;

    做题思路: https://blog.csdn.net/hcy2319964421/article/details/53106578

    我记得之前做这个题目应该是花了2 小时以上, 那时自己刚学编程, 喜欢这种纯粹逻辑 + 规律的思维去解决问题, 但是这种思维的局限性很大:

    1. 单纯的数学规律会让你忽视递归和循环在作用
    2. 有些题目, 数学规律比较繁琐,会随着数据量的增多而变得复杂.

    我甚至很长时间都是这样去思考的, 但是, 今天看到交流群中一个前辈的代码, 我突然有点豁然开朗的感觉:
    对于这种题目: 应该寻找一种解决方式, 适用于所有情况,

    例如这个题目: 每一次累加都是在最外层, 那么我们只需要给上一次的数据加上一个最外层就可以了.

    这里我们发散一下: 我们想象一下编程的本质到底是什么? 我们先来看一组名词

    1. 变量
    2. 函数
    3. 对象
    4. UI框架
    5. 计算机

    上面这一组名词, 其实存在着一个共同的特点, 它们存在的意义之一就是为了消除重复.

    1. 变量的存在是为了消除一个数/对象 重新引用的问题;
    2. 函数的存在是抽象了一种数据的处理方式
    3. 对象的存在是为了抽象一类事物的共同点
    4. UI 框架的存在是为了预定义一些基本的元素类, 加速项目的开发
    5. 计算机的存在是为了计算, 简而言之就是消除人类需要的重复运算

    编程其实解决的最大问题就是消除重复.
    我们做的应该是, 找到一种解决方法, 它适用于一个特殊场景; 而对于其他不是改场景的内容, 我们可以将其改造成为这个场景

    5. 小彩蛋

    将上面代码的 createGraphics 函数作如下更改, 输出内容将会变得非常奇怪, 思考一下这是为什么
    更改:

    const createGraphics = (number) => {
        let list = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
        let result = [[]]
    
        for (let i = number - 1; i > -1; i--) {
            let len = result[0].length
            let char = list[i]
    
            // 最开始的特殊情况
            if (i === number - 1){
                result[0][0] = char
                continue
            }
    
            let head = getList(char, len + 2)
            // let end = getList(char, len + 2)
            result.unshift(head)
            result.push(head)
    
            dealCenterContent(char, result)
        }
    
        return result
    }
    

    输出内容:

    [
      [ 'A', 'A', 'A', 'A', 'A' ],
      [ 'A', 'A', 'B', 'B', 'B', 'A', 'A' ],
      [ 'A', 'B', 'C', 'B', 'A' ],
      [ 'A', 'A', 'B', 'B', 'B', 'A', 'A' ],
      [ 'A', 'A', 'A', 'A', 'A' ]
    ]
    

    6. 提示

    因为这个, 写该题时, 自己花费了15分钟DeBug(水平堪忧......┭┮﹏┭┮)
    说来也是很奇怪, 这个性质自己是知道的, 为什么DeBug 的时候就是想不起来呢

    const log = console.log.bind(console)
    
    let a = [1, 2, 3]
    let b = [[4, 5, 6]]
    b.unshift(a)
    b.push(a)
    log(b) // [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 1, 2, 3 ] ]
    b[0].push(7)
    log(b) // [ [ 1, 2, 3, 7 ], [ 4, 5, 6 ], [ 1, 2, 3, 7 ] ]
    
  • 相关阅读:
    Can't use Subversion command line client: svn
    SpringMVC配置easyui-datagrid
    找不到提交和更新按钮,subversion不见了,无法更新和上传代码
    静态资源[org.springframework.web.servlet.PageNotFound]
    Field 'id' doesn't have a default value
    MySql 插入数据中文乱码
    Junit 测试 Spring
    mybatis动态SQL
    Mybatis 3.3.0 Log4j配置
    MappingJacksonHttpMessageConverter过期
  • 原文地址:https://www.cnblogs.com/oulae/p/12985134.html
Copyright © 2020-2023  润新知