#1 - 2021-12-3 01:47
妄想是不治之症 (水中月是天上月,眼前喵是心上喵)
例如:
有数组a[1,2,3,4] b[2,6] c[5,6,7]
输出结果
125
225
325
425
126
127
....
顺序不做要求,把4*2*3种可能都列出来就行。

按道理来说应该挺简单的啊……信心满满着手开始写结果差点把头写破了
不明白自己的思维是钻了哪里的牛角尖。
想请教一下正确的解题思路~
(不用直接贴答案代码因为有答案的,只是我不想看,还是希望能自己写出来。)
#2 - 2021-12-3 02:07
(miaow~~~)
循环 a的第一个 到 a的最后一个 现在是第x个
  循环 b的第一个 到 b的最后一个 现在是第y个
    循环 c的第一个 到 c的最后一个 现在是第z个
      无间隔顺序输出 a的第x个 b的第y个 c的第z个 还有换行
#2-1 - 2021-12-3 17:04
妄想是不治之症
(bgm38)我简化了一下那个题目其实……题目的数组个数是根据参数改变的,就是有可能是一个,有可能是两个,有可能是三个
#3 - 2021-12-3 03:17
(此账号已停用)
考虑4x3怎么写,a1-4循环,结束后b+1 a重置为1

然后外面套一层就是同样写法的12x2
#3-1 - 2021-12-3 17:10
妄想是不治之症
和楼上一样,数组个数不确定的时候怎么办呢……
#3-2 - 2021-12-3 18:07
红炉点雪
妄想是不治之症 说: 和楼上一样,数组个数不确定的时候怎么办呢……
写个数组把每组的循环计数x都放进去,再写个重置数组值的子函数和大的For循环放在一起
这是考虑代码的美观性,就三四个也没必要这么写就是了
#4 - 2021-12-3 03:23
删除了回复
#5 - 2021-12-3 17:17
(水中月是天上月,眼前喵是心上喵)
算了可能本身我的思路就有问题……

原题目是这样的:

一个pin码按照以下格式排列
1 2 3
4 5 6
7 8 9
   0

假设有一个疑似pin码,如“235”
那么2的疑似数字有[1,2,3,5]
3的疑似数字有[2,3,6]
5的疑似数字有[2,4,5,6,8]

写一个function(x),输出结果为所有可能的pin码
就是122,124,125,126……

我信心满满开始写,然后直接卡在了最后一步……(bgm38)
#6 - 2021-12-3 17:26
(水中月是天上月,眼前喵是心上喵)
还是以主贴的三个数组为例,我的思路是把每一个数组的所有值都分别插进下一个数组的每一个数的前面,例如
把数组b变成[12,22,32,42,6]
再循环成[12,22,32,42,16,26,36,46]
再把这个数组插进下一个数组的每一个数
以此类推
就只需要写三层循环
一层循环总数组个数,一层循环上一个数组里的每一个数,一层循环下一个数组的每一个数
数组的数可以用arr.length不用实际数据。
这样循环下去应该不管多少个数组都能无限算下去的。
完美解决数组个数不固定的问题
但是!

捏吗的写了我两个小时没写出来。
不是报错就是一堆乱码
甚至有次搞出了死循环
(bgm38)(bgm38)(bgm38)
#6-1 - 2021-12-3 17:51
长长的坡道
为什么要这样,定义一个辅助数组不就好了
#7 - 2021-12-3 17:32
这题很像另外一道啊,基本一模一样的,就是按九宫格输入法可能打出来的所有字符串,leetcode上有
#7-1 - 2021-12-3 17:37
#7-2 - 2021-12-3 17:43
妄想是不治之症
我是在codewars上面做的,就是不想看答案……(只是给提示没有给答案的话就是我自己写出来的!耶)
#8 - 2021-12-3 17:34
(hhh汝视视汝)
这个操作叫笛卡尔积

思路1: 递归


function* r(g1, ...rest) { if (!rest.length) { for(const v of g1||[]) yield [v] } else for(const x of r(...rest)) for(const v of g1) yield [v, ...x] }
return Array.from(r([1,2,3,4],[2,6],[5,6,7]))



思路2: 称 N是所有输入数组长度的乘积,则结果中的每一项对应一个[0, N) 之间的整数
所以可以两层循环,外层让n在[0, N)间循环,内层把n还原成每个原数组中的index
#8-1 - 2021-12-3 17:44
妄想是不治之症
这个思路2我好像见过……!但是没怎么理解,我再意会一下
#9 - 2021-12-3 17:41
(水中月是天上月,眼前喵是心上喵)
难以解决的是怎么把上一个数字分别和下一个数字结合然后插进下一个数组的前头,最后还要删掉原来的数据,
不然就会变成[122232422,162636466]……(bgm38)(bgm38)(bgm38)
#9-1 - 2021-12-3 17:45
Retorm
可是你为什么一定要这么改呢,两个还好,数组越多越难想啊,那么为什么不新建一个数组来存呢?(bgm38)
#9-2 - 2021-12-3 17:47
妄想是不治之症
等等我好像想到了……直接新建一个数组啊!就不用想怎么还要删掉原来的2和6了!下班了回去试试(bgm40)
#9-3 - 2021-12-3 17:50
妄想是不治之症
Retorm 说: 可是你为什么一定要这么改呢,两个还好,数组越多越难想啊,那么为什么不新建一个数组来存呢?
我老是忘记用第三者来中转(bgm38)喜欢直接在原数据上面改,因为这样比较符合人类大脑的思路……还是没有习惯用程序的思路想事情(bgm38)

感觉自己又浪费了两个小时的生命,和头发
#9-4 - 2021-12-3 17:53
Retorm
妄想是不治之症 说: 我老是忘记用第三者来中转还是习惯直接在原数据上面改,因为这样比较符合人类大脑的思路。我还是没有习惯用程序的思路想事情

感觉自己又浪费了两个小时的生命,和头发
按理说这其实不是第三者,因为这就是你最后要的结果集合里的一个元素,不论如何你也得给他新分配一个空间的(bgm38)
#10 - 2021-12-3 18:17
(说得很好,那么你的女朋友呢?)
想到了一个思路,试了一下做出来了。
简单来说,这3个数组,先不要看内容,只看index,用它们的index来排数字
a1 = [1,2,3,5];
a2 = [2,3,6];
a3 = [2,4,5,6,8];

在百位放a1,十位放a2,个位放a3,按index排列下来就变成
000, 001, 002, 003, 004, 010, 011, 012, ..., 324
这个三位数的个位是5进制,十位是3进制,百位是4进制,所以把它转换成十进制数的话,公式就是
d = 15*a1 + 5*a2 + a3
从十进制数反推这个三位数的话,公式就是
d / 15 = a1 ... r
r/ 5 = a2 ... a3
能够从十进制数反推三位数之后,就只需要写1个循环,循环总数自然是5*3*4=60
每次循环里面,算出当次循环对应的三位数,然后因为这三位数都是index,所以再用index找到对应的数组的值,就可以得到一组pin码了
#10-1 - 2021-12-3 18:27
#10-2 - 2021-12-3 18:28
妄想是不治之症 说:
nb
其实就是#8的思路2
#11 - 2021-12-3 23:39
(水中月是天上月,眼前喵是心上喵)
前前后后写了70行,大佬就写了几个字。

      function getPINs(observed) {
        return observed
          .split("")
          .map(
            (t) =>
              ({
                0: ["0", "8"],
                1: ["1", "2", "4"],
                2: ["1", "2", "3", "5"],
                3: ["2", "3", "6"],
                4: ["1", "4", "5", "7"],
                5: ["2", "4", "5", "6", "8"],
                6: ["3", "5", "6", "9"],
                7: ["4", "7", "8"],
                8: ["5", "7", "8", "9", "0"],
                9: ["6", "8", "9"],
              }[t])
          )
          .reduce((pre, cur) =>
            [].concat.apply(
              [],
              pre.map((t) => cur.map((g) => t + g))
            )
          );
      }
#12 - 2022-1-9 01:27
(19914)
就是简单回溯吧 贡献一个lc风格的 (逃
var mtx = [[1, 2, 3, 4], [2, 6], [5, 6, 7]]
var result = []
function helper(i, str) {
    var orig = str
    if (i == 3) {
        result.push(str)
        console.log(str)
        return
    }
    for (let j = 0; j < mtx[i].length; j++) {
        str += mtx[i][j]
        helper(i + 1, str)
        str = orig
    }
}

helper(0, "")


想起以前被前端问到一个父子列表转多叉树的问题(形如[{pid:0,id:1},{pid:1,id:2}]的列表转成树喂cascader), 也是很典型而且很实用的递归问题。