成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

一篇學(xué)會(huì)字符串的排列

開(kāi)發(fā) 前端
排列方案的生成:根據(jù)字符串排列的特點(diǎn),考慮深度優(yōu)先搜索所有排列方案。即通過(guò)字符交換,先固定第1位字符( n種情況)、再固定第2位字符(n-1種情況)、...、最后固定第n位字符(1種情況)。

[[439357]]

本文轉(zhuǎn)載自微信公眾號(hào)「程序員千羽」,作者程序員千羽。轉(zhuǎn)載本文請(qǐng)聯(lián)系程序員千羽公眾號(hào)。

 Leetcode : https://leetcode-cn.com/problems/zi-fu-chuan-de-pai-lie-lcof/

“GitHub : https://github.com/nateshao/leetcode/blob/main/algo-notes/src/main/java/com/nateshao/sword_offer/topic_30_permutation/Solution.java

字符串的排列

“題目描述 :輸入一個(gè)字符串,打印出該字符串中字符的所有排列。你可以以任意順序返回這個(gè)字符串?dāng)?shù)組,但里面不能有重復(fù)元素。為了讓您更好地理解問(wèn)題,以下面的二叉搜索樹(shù)為例:難度:中等示例:

  1. 輸入:s = "abc" 
  2.  
  3. 輸出:["abc","acb","bac","bca","cab","cba"

解題思路:

對(duì)于一個(gè)長(zhǎng)度為 n 的字符串(假設(shè)字符互不重復(fù)),其排列方案數(shù)共有:

排列方案的生成:根據(jù)字符串排列的特點(diǎn),考慮深度優(yōu)先搜索所有排列方案。即通過(guò)字符交換,先固定第1位字符( n種情況)、再固定第2位字符(n-1種情況)、...、最后固定第n位字符(1種情況)。

重復(fù)排列方案與剪枝:當(dāng)字符串存在重復(fù)字符時(shí),排列方案中也存在重復(fù)的排列方案。為排除重復(fù)方案,需在固定某位字符時(shí),保證“每種字符只在此位固定一次” ,即遇到重復(fù)字符時(shí)不交換,直接跳過(guò)。從DFS角度看,此操作稱(chēng)為"剪枝” 。

遞歸解析:

  • 終止條件: 當(dāng) x = len(c) - 1 時(shí),代表所有位已固定(最后一位只有 11 種情況),則將當(dāng)前組合 c 轉(zhuǎn)化為字符串并加入 res ,并返回;
  • 遞推參數(shù): 當(dāng)前固定位 x ;
  • 遞推工作: 初始化一個(gè) Set ,用于排除重復(fù)的字符;將第 x 位字符與 i ∈ [x, len(c)] 字符分別交換,并進(jìn)入下層遞歸;
    • 剪枝: 若 c[i] 在 Set 中,代表其是重復(fù)字符,因此 “剪枝” ;
    • 將 c[i] 加入 Set ,以便之后遇到重復(fù)字符時(shí)剪枝;
    • 固定字符: 將字符 c[i] 和 c[x] 交換,即固定 c[i] 為當(dāng)前位字符;
    • 開(kāi)啟下層遞歸: 調(diào)用 dfs(x + 1) ,即開(kāi)始固定第 x + 1 個(gè)字符;
    • 還原交換: 將字符 c[i] 和 c[x] 交換(還原之前的交換);

下圖中 list 對(duì)應(yīng)文中的列表 c 。比如

舉個(gè)例子:

  1. 通過(guò)交換來(lái)固定某個(gè)位置的元素這個(gè)思路, 
  2. 就 abc 這個(gè)字符串來(lái)說(shuō),第一個(gè)位置可以放 a 或者 b 或者 c,但是如果確定要放某個(gè)字符, 
  3. 比如第一個(gè)位置放 a,那么第二個(gè)位置就只能放 b 或者 c; 
  4. 如果第一個(gè)位置放 b,那么第二個(gè)位置就只能放 a 或者 c; 
  5. 如果第一個(gè)位置放 c,那么第二個(gè)位置就只能放 a 或者 b; 
  6. 當(dāng)把某個(gè)字符移動(dòng)到第一位以后,暫時(shí)第一位的字符就固定住了, 
  7. 這時(shí)再去確定第二個(gè)位置的元素,并且此時(shí)第一個(gè)位置的元素不會(huì)再出現(xiàn)在后面的位置上, 
  8. 依次類(lèi)推直到確定所有位置的元素,再往前回溯確定每個(gè)位置上其他可能出現(xiàn)的元素。 

復(fù)雜度分析:

  • 時(shí)間復(fù)雜度0(N!N) :N為字符串s的長(zhǎng)度;時(shí)間復(fù)雜度和字符串排列的方案數(shù)成線性關(guān)系,案數(shù)為N x(N- 1)x (N- 2)...x2x1,即復(fù)雜度為0(N!) ;

字符串拼接操作join() 使用O(N)因此總體時(shí)間復(fù)雜度為O(N!N)。

  • 空間復(fù)雜度0(N2) :全排列的遞歸深度為N,系統(tǒng)累計(jì)使用棧空間大小為0(N) ;

遞歸中輔助Set累計(jì)存儲(chǔ)的字符數(shù)量最多為N +(N- 1)+...+2+1=(N + 1)N/2 ,即占用O(N2)的額外空間。

  1. package com.nateshao.sword_offer.topic_30_permutation; 
  2.  
  3. import java.util.ArrayList; 
  4. import java.util.Collections; 
  5. import java.util.HashSet; 
  6. import java.util.List; 
  7.  
  8. /** 
  9.  * @date Created by 邵桐杰 on 2021/12/2 15:31 
  10.  * @微信公眾號(hào) 程序員千羽 
  11.  * @個(gè)人網(wǎng)站 www.nateshao.cn 
  12.  * @博客 https://nateshao.gitee.io 
  13.  * @GitHub https://github.com/nateshao 
  14.  * @Gitee https://gitee.com/nateshao 
  15.  * Description: 劍指 Offer 38. 字符串的排列 
  16.  */ 
  17. public class Solution { 
  18.  
  19.     public static void main(String[] args) { 
  20.         String str = "abc"
  21.         ArrayList<String> list = permutation2(str); 
  22.         list.stream().forEach(lists-> System.out.print( lists+" " )); // abc acb bac bca cab cba 
  23.         System.out.println(); 
  24.         for (String s : list) { 
  25.             System.out.print(s + " "); // abc acb bac bca cab cba 
  26.         } 
  27.     } 
  28.      
  29.     /** 
  30.      * 劍指offer 
  31.      * 解題思路:將當(dāng)前位置的字符和前一個(gè)字符位置交換,遞歸. 
  32.      * @param str 
  33.      * @return 
  34.      */ 
  35.     public static ArrayList<String> permutation2(String str) { 
  36.         ArrayList<String> res = new ArrayList<>(); 
  37.         if (str == nullreturn res; 
  38.         helper(res, 0, str.toCharArray()); 
  39.         // 符合結(jié)果的輸出順序 
  40.         Collections.sort(res); 
  41.         return res; 
  42.  
  43.     } 
  44.  
  45.     private static void helper(ArrayList<String> res, int indexchar[] s) { 
  46.         if (index == s.length - 1) { 
  47.             res.add(String.valueOf(s)); 
  48.             return
  49.         } 
  50.         for (int i = index; i < s.length; i++) { 
  51.             if (i == index || s[index] != s[i]) { 
  52.                 swap(s, index, i); 
  53.                 helper(res, index + 1, s); 
  54.                 swap(s, index, i); 
  55.             } 
  56.         } 
  57.     } 
  58.      
  59.     public static void swap(char[] c, int a, int b) { 
  60.         char temp = c[a]; 
  61.         c[a] = c[b]; 
  62.         c[b] = temp
  63.     } 
  64.     /********************** 精選解答 **************************/ 
  65.     //為了讓遞歸函數(shù)添加結(jié)果方便,定義到函數(shù)之外,這樣無(wú)需帶到遞歸函數(shù)的參數(shù)列表中 
  66.     List<String> list = new ArrayList<>(); 
  67.     //同;但是其賦值依賴(lài)c,定義聲明分開(kāi) 
  68.     char[] c; 
  69.     public String[] permutation(String s) { 
  70.         c = s.toCharArray(); 
  71.         //從第一層開(kāi)始遞歸 
  72.         dfs(0); 
  73.         //將字符串?dāng)?shù)組ArrayList轉(zhuǎn)化為String類(lèi)型數(shù)組 
  74.         return list.toArray(new String[list.size()]); 
  75.     } 
  76.  
  77.     public void dfs(int x) { 
  78.         //當(dāng)遞歸函數(shù)到達(dá)第三層,就返回,因?yàn)榇藭r(shí)第二第三個(gè)位置已經(jīng)發(fā)生了交換 
  79.         if (x == c.length - 1) { 
  80.             //將字符數(shù)組轉(zhuǎn)換為字符串 
  81.             list.add(String.valueOf(c)); 
  82.             return
  83.         } 
  84.         //為了防止同一層遞歸出現(xiàn)重復(fù)元素 
  85.         HashSet<Characterset = new HashSet<>(); 
  86.         //這里就很巧妙了,第一層可以是a,b,c那么就有三種情況,這里i = x,正巧dfs(0),正好i = 0開(kāi)始 
  87.         // 當(dāng)?shù)诙又挥袃煞N情況,dfs(1)i = 1開(kāi)始 
  88.         for (int i = x; i < c.length; i++){ 
  89.             //發(fā)生剪枝,當(dāng)包含這個(gè)元素的時(shí)候,直接跳過(guò) 
  90.             if (set.contains(c[i])){ 
  91.                 continue
  92.             } 
  93.             set.add(c[i]); 
  94.             //交換元素,這里很是巧妙,當(dāng)在第二層dfs(1),x = 1,那么i = 1或者 2, 不是交換1和1,要就是交換1和2 
  95.             swap(i,x); 
  96.             //進(jìn)入下一層遞歸 
  97.             dfs(x + 1); 
  98.             //返回時(shí)交換回來(lái),這樣保證到達(dá)第1層的時(shí)候,一直都是abc。這里捋順一下,開(kāi)始一直都是abc,那么第一位置總共就3個(gè)交換 
  99.             //分別是a與a交換,這個(gè)就相當(dāng)于 x = 0, i = 0; 
  100.             //     a與b交換            x = 0, i = 1; 
  101.             //     a與c交換            x = 0, i = 2; 
  102.             //就相當(dāng)于上圖中開(kāi)始的三條路徑 
  103.             //第一個(gè)元素固定后,每個(gè)引出兩條路徑, 
  104.             //     b與b交換            x = 1, i = 1; 
  105.             //     b與c交換            x = 1, i = 2; 
  106.             //所以,結(jié)合上圖,在每條路徑上標(biāo)注上i的值,就會(huì)非常容易好理解了 
  107.             swap(i,x); 
  108.         } 
  109.     } 
  110.     private void swap(int i, int x) { 
  111.         char temp = c[i]; 
  112.         c[i] = c[x]; 
  113.         c[x] = temp
  114.     } 

參考文章:https://leetcode-cn.com/problems/zi-fu-chuan-de-pai-lie-lcof/solution/mian-shi-ti-38-zi-fu-chuan-de-pai-lie-hui-su-fa-by

 

責(zé)任編輯:武曉燕 來(lái)源: 程序員千羽
相關(guān)推薦

2021-11-29 08:49:37

字符串轉(zhuǎn)換整數(shù)

2023-03-07 10:07:04

JavaScript字符串反斜杠

2022-02-07 11:01:23

ZooKeeper

2022-01-02 08:43:46

Python

2021-11-15 07:47:40

字符串位置存儲(chǔ)

2021-05-28 10:02:05

Swift5 字符串String

2021-12-04 22:05:02

Linux

2021-10-26 10:40:26

代理模式虛擬

2022-05-17 08:02:55

GoTryLock模式

2022-06-30 22:53:18

數(shù)據(jù)結(jié)構(gòu)算法

2021-08-01 07:19:16

語(yǔ)言OpenrestyNginx

2021-09-28 08:59:30

復(fù)原IP地址

2021-10-14 10:22:19

逃逸JVM性能

2022-04-12 08:30:52

回調(diào)函數(shù)代碼調(diào)試

2021-10-27 09:59:35

存儲(chǔ)

2021-07-16 22:43:10

Go并發(fā)Golang

2023-03-13 21:38:08

TCP數(shù)據(jù)IP地址

2023-11-01 09:07:01

Spring裝配源碼

2022-10-20 07:39:26

2022-03-11 10:21:30

IO系統(tǒng)日志
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 国产午夜精品一区二区三区在线观看 | 亚洲视频免费播放 | 国产精品一区二区av | 亚洲成人精品一区 | 亚洲成人精品 | 国产视频黄色 | 日本 欧美 国产 | 黄网站涩免费蜜桃网站 | 一区二区三区高清在线观看 | 成人在线免费网站 | 成人午夜精品 | 国产成人精品一区二 | 综合久久久 | 精品久久久久久久人人人人传媒 | 九九99久久 | 超碰97干 | 人人做人人澡人人爽欧美 | 色综合久久久 | 在线91| 在线一区 | 久久久蜜臀国产一区二区 | 亚洲成人久久久 | 日韩免费高清视频 | www.伊人.com | 综合久久av | 九色视频网站 | 中文字幕在线观看 | 日本午夜一区二区三区 | 爱草在线 | 一级片免费视频 | 日本福利视频免费观看 | 久久久综合色 | 91国内产香蕉| 亚洲精品粉嫩美女一区 | 色偷偷888欧美精品久久久 | 又黄又色 | 另类视频在线 | 精品欧美乱码久久久久久 | 亚洲一区二区三区四区五区中文 | 成人av片在线观看 | 精品久久久精品 |