在编程时经常会有类似的算法:从第一个元素或最后一个元素开始往后或往前遍历,遍历到符合条件的位置时,对该位置之前或之后的已遍历元素进行运算,然后返回对应值。使用REDUCE函数的X,可以实现类似的用法,X就是已遍历元素的集合,不满足条件的时候逐个装入y,待满足条件后,对当前的X进行运算。
题目:找到下一个排列,下一个排列是指如果数组的所有排列从小到大排列后排在它后面的那个数。如果不存在下一个更大的排列,那么这个数必须重排为最小的排列。
例如:123的下一个排列是132,132是比123大的,且各位数字数量都和123的各位数字数量一致,也可以说是对123的各位数字进行重新组合,生成的大于123的最小数字 。类似地,231的下一个排列是312。而321的下一个排列是123,因为321不存在一个字典序更大的排列。更多示例如下:
- =LET(s,LEFT(RIGHT(A2,SEQUENCE(LEN(A2)))),u,--CONCAT(REDUCE(,s,LAMBDA(x,y,LET(w,VSTACK(y,x),v,SORTBY(w,w>y,-1,w,1),IF(OR(y>=@x,x=""),w,VSTACK(@v,SORT(DROP(v,1)),"")))))),IF(u=A2,--CONCAT(SORT(s)),u))
复制代码
首先数字最右侧开始取,倒序取出数字中的每一个数字;然后判断当前数字是不是大于上一个装入X的数字,如果是的话,当前的y和X中大于y的最小值交换,然后交换后的X进行排序。具体算法可以参考:https://blog.csdn.net/m0_63988748/article/details/125598526。核心在于X存储了已经遍历过的元素。
如果不用REDUCE函数,也可以用其他方法实现下一个排列的计算,例如:
- =LET(s,MID(0&A2,ROW($1:11),1),t,XMATCH(1=1,s<DROP(s,1),,-1),w,DROP(s,t-1),v,SORTBY(w,w>@w,-1,w,1),--IFERROR(CONCAT(TAKE(s,t-1),@v,SORT(DROP(v,1))),CONCAT(SORT(s))))
复制代码
|