更新時間:2020-10-19 17:55:23 來源:動力節(jié)點 瀏覽1050次
求解字符串全排列一直是字符串相關(guān)問題中最常見的問題之一。雖然看起來很簡單,仍困擾著許許多多的Java初學(xué)者。本文我們就來給出字符串全排列的解答方案供大家參考。
我們在第一次遇見字符串全排列這個問題的時候不要慌張,放輕松,然后冷靜思考,接下來我們來看下如何實現(xiàn)這道題。
首先我們來看下問題是什么。
給定一個字符串,求出這個字符串所有可能出現(xiàn)的排列組合。
如: abc
輸出:
[ 'cba', 'bca', 'cab', 'acb', 'bac', 'abc' ]
準(zhǔn)備好了嗎? 來一起看下如何實現(xiàn)吧。
解答思路:
首先我們來做個假設(shè):
當(dāng)前給的字符串為 'a' 。那么返回的只有一個排列 [ 'a' ]。
當(dāng)前給的字符串為 'ab' 。則返回 [ 'ab', 'ba' ]。
當(dāng)前給的字符串為 'abc' 。則返回 [ 'cba', 'bca', 'cab', 'acb', 'bac', 'abc' ]。
………………
1. 一個字符的情況
乍一看好像沒什么規(guī)律,不急,我們先來實現(xiàn)以下只有一個字符的情況:
const str = 'a'
function fullPer (str) {
return [str]
}
fullPer(str) // [ 'a' ]
相信這個代碼大家都會寫。接下來,難度繼續(xù)深入。
2. 兩個字符的情況
第二步,我們需要添加兩個字符的情況。兩個的情況下,為了便于我們理解,我們使用遞歸的方式實現(xiàn)。
使用遞歸我們需要先找到以下幾個條件
何時結(jié)束:str 的長度為 1 的時候
如何遞進(jìn):每次留一個字符,然后與剩下的字符相加
返回結(jié)果:返回一個數(shù)組
const str = 'ab'
function fullPer(str) {
if (str.length <= 1) {
return [str]
}
let result = [] // 定義一個結(jié)果集,用來收集所有的排列
for(let i = 0,len = str.length;i < len; i ++) {
let child = str[i] // 保留當(dāng)前字符
let last = str.replace(child, '') // 獲得剩下的所有字符
result.push(fullPer(last)[0] + child) // 將得到的下一個字符與當(dāng)前字符做拼接
}
return result // 將得到的結(jié)果返回
}
fullPer(str) // [ 'ba', 'ab' ]
解釋一下:
兩個字符的情況下,我們寫的代碼數(shù)量明顯比一個字符的情況多很懂,所以不好理解,那我們就來解釋一下代碼。
代碼中,如果我們當(dāng)前保留的字符是 a 的話,那么下一次傳入的就是 b 。然后字符長度為1,不做處理,直接返回一個數(shù)組。之后我們將得到的字符b與保留字符a相加,得到 ba
同樣的道理,保留字符為 b ,下次傳入 a,得到 ab
將兩次的結(jié)果分別添加到結(jié)果集中,返回得到 [ 'ba', 'ab' ]
3. 三個字符的情況
三個字符與兩個字符相差不大,只不過我們需要變動得到字符之后的處理。我們來看下代碼:
const str = 'abc'
function fullPer(str) {
if (str.length <= 1) {
return [str]
}
let result = []
for(let i = 0,len = str.length;i < len; i ++) {
let child = str[i]
let last = str.replace(child, '')
// 唯一與第二步不一樣的地方
const middle = fullPer(last).map(item => item + child)
// 因為這里得到的是一個數(shù)組,所以我們需要將result與middle做拼接
result = result.concat(middle)
}
return result
}
fullPer(str) // [ 'cba', 'bca', 'cab', 'acb', 'bac', 'abc' ]
解釋一下:
三個字符的情況,我們得到的是一個多元素的數(shù)組,所以只能通過遍歷的方式都添加上之前所保留的字符child
結(jié)果集也不能使用push,得使用 concat 將兩個數(shù)組做拼接。
4. 三個字符以上的情況
我們先驗證一下其他數(shù)量字符的情況下,上邊的函數(shù)能不能用,這里我們就輸出結(jié)果的總數(shù),不輸出具體值了。
// 四個字符
const str = 'abcd'
fullPer(str).length // 24
// 五個字符
const str = 'abcd3'
fullPer(str).length // 120
根據(jù)階乘公式可知,我們得到的是正確答案。我們直到解決完整個問題才發(fā)現(xiàn)其實問題本身并不復(fù)雜,而是我們?nèi)菀紫氲膹?fù)雜,反而影響了思路。相信看完了本文的小伙伴都能獨自完成字符串全排列的解答,也可以在本站的Java零基礎(chǔ)入門教程中學(xué)習(xí)新的解答方法,多給自己一點學(xué)習(xí)和進(jìn)步的空間!
初級 202925
初級 203221
初級 202629
初級 203743