<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          數(shù)組全排列問題

          共 2380字,需瀏覽 5分鐘

           ·

          2022-01-07 21:41

          題目:

          給定一個(gè)數(shù)組,打印出數(shù)組的所有排列。比如數(shù)組為[1, 2, 3],那最終輸出為:

          [1, 2, 3][1, 3, 2][2, 1, 3][2, 3, 1][3, 1, 2][3, 2, 1]

          就是把數(shù)組的所有順序的可能都輸出出來。

          解題思路

          1、遞歸解法


          思路

          遞歸的主旨思想就是把問題轉(zhuǎn)化成一個(gè)或幾個(gè)更小規(guī)模的子問題,比如說[1, 2, 3]的全排列不好處理,那我們固定第一位是1,然后求[2, 3]的全排列,然后再把第一位固定為2,求[1, 3]的全排列,最后把第一位固定成3,求[1, 2]的全排列。這樣,經(jīng)過層層推演,可以把題目轉(zhuǎn)換成求長(zhǎng)度為1的數(shù)組的全排列,很顯然就得到答案了。


          進(jìn)一步解析

          上面的思想是基本沒什么問題的,但是怎么實(shí)現(xiàn)固定第一位呢,這里有個(gè)比較巧妙的方法,就是讓第一位分別和后面幾位進(jìn)行交換,這樣每個(gè)數(shù)字都會(huì)被固定在第一位一次,然后遞歸進(jìn)行后面的操作,注意為了復(fù)用當(dāng)前的數(shù)組,而不是每次都進(jìn)行值拷貝,每次遞歸執(zhí)行完了,要把之前的順序換回來,這樣就確保了一個(gè)父問題處理多個(gè)子問題的時(shí)候不會(huì)因?yàn)槟硞€(gè)子問題改變了數(shù)組順序,而無法處理下一個(gè)子問題了,具體來看下代碼:


          // 遞歸函數(shù)function _allSort(arr, start, len) {  // arr: 要全排列的數(shù)組,start: 從數(shù)組的start位置之后開始全排列,len: 數(shù)組總長(zhǎng)度  for (let i = start; i < len; i++) {    if (start == len - 1) {      // 如果當(dāng)前全排列已經(jīng)是最后一位了,則輸出數(shù)組      console.log(arr)    } else {      // 將start位置與各個(gè)位置交換      swap(i, start, arr)      // 交換完start自增1,處理子問題      _allSort(arr, start + 1, len)      // 交換完再換回來,確保每個(gè)子問題執(zhí)行完,不影響父問題的順序      swap(start, i, arr)    }  }}// 位置交換function swap (a, b, nums) {  let temp = nums[a]  nums[a] = nums[b]  nums[b] = temp}// 從0位置開始全排列function allSort(arr) {  let start = 0  let len = arr.length  _allSort(arr, start, len)}
          allSort([1,2,3])


          存在重復(fù)的問題

          上面的代碼,在數(shù)組沒有重復(fù)元素的時(shí)候運(yùn)行是正常的,但是一旦有重復(fù)就會(huì)出現(xiàn)一些小問題,我們看下arr為[1, 2, 2]的執(zhí)行結(jié)果:



          [1, 2, 2][1, 2, 2][2, 1, 2][2, 2, 1][2, 2, 1][2, 1, 2]


          發(fā)現(xiàn)沒,有一些組合是重復(fù)的,針對(duì)這些情況,需要做一些過濾,拿[1, 2, 2]進(jìn)行舉例,當(dāng)1和第一個(gè)2交換時(shí)正常交換,但是當(dāng)1和第二個(gè)2交換的時(shí)候就要判定之前之前有沒有和2交換過,基于此我們升級(jí)一下代碼:


          // 遞歸函數(shù)function _allSort(arr, start, len) {  // arr: 要全排列的數(shù)組,start: 從數(shù)組的start位置之后開始全排列,len: 數(shù)組總長(zhǎng)度  for (let i = start; i < len; i++) {    if (start == len - 1) {      // 如果當(dāng)前全排列已經(jīng)是最后一位了,則輸出數(shù)組      console.log(arr)    } else {      // 判定當(dāng)前元素是否重復(fù)出現(xiàn)      let is_mutil = false      for (let j = start; j < i; j++) {        if (arr[j] === arr[i]) {          console.log(arr[j], arr[i])          is_mutil = true          break        }      }      if (is_mutil) {        // 如果已經(jīng)出現(xiàn)過,就不在生成新的子問題了        continue      }      // 將start位置與各個(gè)位置交換      swap(i, start, arr)      // 交換完start自增1,處理子問題      _allSort(arr, start + 1, len)      // 交換完再換回來,確保每個(gè)子問題執(zhí)行完,不影響父問題的順序      swap(start, i, arr)    }  }}// 位置交換function swap (a, b, nums) {  let temp = nums[a]  nums[a] = nums[b]  nums[b] = temp}// 從0位置開始全排列function allSort(arr) {  let start = 0  let len = arr.length  _allSort(arr, start, len)}
          allSort([1,2,2])


          這樣就成功解決了有重復(fù)數(shù)據(jù)的問題,不過同時(shí)也提升了時(shí)間復(fù)雜度。


          瀏覽 38
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  天天爽日日澡AAAA片 | 午夜操逼视频 | 天天日天天噜 | 骚虎官网在线观看 | 波多野结衣在线观看一区二区 |