鍍金池/ 問(wèn)答/Java  Python  C++  HTML/ 邏輯題目,給定26!字母排列(有規(guī)律),給 任意數(shù)字 求出 排列的結(jié)果?

邏輯題目,給定26!字母排列(有規(guī)律),給 任意數(shù)字 求出 排列的結(jié)果?

假如有abc,共有3!的排列結(jié)果,
排列順序是 abc acb bac bca cab cba
給任意數(shù)字,比如N=4,就要輸出bca。

現(xiàn)在有26英文字母,共26!種排列方式,給任意數(shù)字N,該如何求出字母列?

聽(tīng)別人說(shuō)用遞歸就可以解決,但實(shí)在想不出什么解法

回答
編輯回答
誮惜顏

https://blog.csdn.net/u010271...
這個(gè)例子中的result就是最后放結(jié)果的數(shù)組,順序有問(wèn)題的話,直接調(diào)用一下sort()方法,就是按照字母順序排列的數(shù)組了。
然后index訪問(wèn)result數(shù)組就是想要的結(jié)果。

2017年8月11日 09:48
編輯回答
網(wǎng)妓

有意思,一看題目我想到的就是先把排列全部算一遍組成一個(gè)數(shù)組,然后任意數(shù)字N直接從這個(gè)數(shù)組里面索引出來(lái)就是結(jié)果了。
我目前的思路是如果規(guī)律固定即abc acb bac bca cab cba的話,把26個(gè)字母拆分成數(shù)組,每個(gè)位的字母在相應(yīng)數(shù)字下應(yīng)該有個(gè)算法可以得出位移目標(biāo),但是具體算法還得抽空想想,實(shí)現(xiàn)了再追答


hfhan 已經(jīng)給出實(shí)現(xiàn)算法,很贊

2017年5月28日 09:44
編輯回答
離夢(mèng)

遞歸是能解決,這么說(shuō)吧,遞歸的思想就是將大問(wèn)題化作小問(wèn)題,那么這個(gè)問(wèn)題怎么來(lái)劃分呢?就以 abcd 為例子看一下。

因?yàn)榕帕薪Y(jié)果共有 4!種,并且由于是順序,那么:

  • 第一位就有 4 種可能,剩余三位共有 3! 種
  • 第二位就有 3 種可能,剩余兩位共有 2! 種
  • 第三位就有 2 種可能,剩余一位共有 1! 種

所以,假設(shè) N = 9,那么根據(jù)上面的過(guò)程,第一位如果是 a,那么其余位共有 3! 種可能,由于 3! < 9,那么第一位必然不是 a,所以要遞增一位,改為 b,加上之前 a 的組合數(shù),3!+ 3!> 9,所以無(wú)論最后的排列是什么,這個(gè)排列的第一位肯定是 b,之后問(wèn)題求解規(guī)模就縮小了,相當(dāng)于在 acd 三個(gè)字母中的,求當(dāng) N = 3 的排列結(jié)果,直到你找到所有位的字母(也就是 N = 0 的時(shí)候)。

轉(zhuǎn)化的過(guò)程大概是這樣的(*代表未知字母):

  • s = xxxx, N = 9
  • s = bxxx, N = 3
  • s = bcxx, N = 1
  • s = bcad, N = 0

如有錯(cuò)誤,還望指正,大神輕噴

2017年3月25日 05:35
編輯回答
不討囍
//共有 count 種排列方式
var counts = Object.create(null)
function getCount(len){
    if(!counts[len]){
        var count = 1;
        while(len > 1){
            count *= len
            len--
        }
        counts[len] = count
    }
    return counts[len]
}

var getStr = function(arr){
    //if(!Array.isArray(arr))return;
    if(Object.prototype.toString.call(arr) !== "[object Array]")return;
    
    var len = arr.length
    
    return function(n){
        if(n < 1){
            alert('數(shù)值超出下限,錯(cuò)誤')
            return false
        }
        if(n > getCount(len = arr.length)){
            alert('數(shù)值超出上限,錯(cuò)誤')
            return false
        }
        n -= 1;//在計(jì)數(shù)中下標(biāo)從0開(kāi)始
        
        var index = 0,
            newArr = arr.slice(),
            resulte = [],
            count = 0
        
        //一位一位的獲取元素
        while(len > 1){
            //獲取改長(zhǎng)度下的可能組合數(shù)
            count = getCount(len)
            //用n的值算出剩余元素首位元素在數(shù)組中的位置
            //比如5位的數(shù)組可能組合有120種,那么第110個(gè)(下標(biāo)0開(kāi)始)的組合的首位元素就是
            // 110*5/120 | 0 = 4,下標(biāo)4,也就是e
            index = n*len/count | 0
            //從數(shù)組中刪除這個(gè)元素,并追加到結(jié)果集合中
            resulte.push(newArr.splice(index,1))
            //從第一種組合到下標(biāo)為4的元素排第一的組合數(shù)占去了 4*120/5 個(gè)
            // 那么相對(duì)剩余幾個(gè)元素組合數(shù)的位置就變成了
            // n = 110 - 4*120/5 = 14
            n -= index*count/len
            len--
        }
        //追加最后一個(gè)元素
        len == 1 && resulte.push(newArr[0])
        
        console.log(resulte.join(''))
    }
}(['a','b','c','d','e'])

getStr(1); // 'abcde'
getStr(4); // 'abdec'
getStr(120); // 'edcba'
getStr(119); // 'edcab'
2017年6月17日 02:06