日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

leetcode:活字印刷

發(fā)布時(shí)間:2024/3/12 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 leetcode:活字印刷 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目來(lái)源:力扣

題目描述:

你有一套活字字模 tiles,其中每個(gè)字模上都刻有一個(gè)字母 tiles[i]。返回你可以印出的非空字母序列的數(shù)目。
====================================================
輸入:“AAB”
輸出:8
解釋:可能的序列為 “A”, “B”, “AA”, “AB”, “BA”, “AAB”, “ABA”, “BAA”。
===================================================
提示:
1 <= tiles.length <= 7
tiles 由大寫英文字母組成

審題:

本題有點(diǎn)類似與排列組合中的排列問(wèn)題,其中子集的大小可以為任意大小但非空.本題主要的復(fù)雜性在于字符串中可能存在重復(fù)字符.

對(duì)于這類題目,大都可以使用回溯的思路解決,區(qū)別在于考慮每一步的可能選擇子集.如果字符串中不包含重復(fù)值,則我們的下一步可以選擇任意未被選中的字符,或者不選(在第一步我們必須選擇一個(gè)值,因?yàn)樽罱K結(jié)果字符串不能為空).而由于存在重復(fù)字符,因此我們選擇第一個(gè)字符’A’與第二個(gè)字符’A’對(duì)最終的結(jié)果是沒(méi)有任何區(qū)別的,如果按照原有思路,則會(huì)存在重復(fù)計(jì)數(shù).因此,對(duì)于存在重復(fù)字符的字符串,我們的每一步選擇只能在所有未被選擇且不重復(fù)的字符中選擇.

可以使用鍵值對(duì)結(jié)構(gòu)保存字符串中每一個(gè)字符的個(gè)數(shù),基于此,我們的每一步選擇即為所有值不為空的鍵,或者空集(在第一步不能選擇空);當(dāng)我們選擇空集時(shí),表示當(dāng)前選擇結(jié)束,計(jì)數(shù)+1;

java算法:

class Solution {Map<Character, Integer> map = new HashMap<>();int totalNum;//當(dāng)前可選的字符集合為所有至不為0的鍵,或者不選任何元素,直接返回private void dfs(boolean end){//如果構(gòu)建結(jié)束,則計(jì)數(shù)+1if(end){totalNum++;return;}for(Character k: map.keySet()){if(map.get(k) != 0){System.out.println(k);map.put(k, map.get(k)-1); //入棧,該鍵對(duì)應(yīng)的值減1dfs(false); //由于我們?cè)谠摬竭x擇了字符k,所以選擇并未結(jié)束,傳入falsemap.put(k, map.get(k)+1); //退棧,該鍵對(duì)應(yīng)的值加1}}//從第二步起,在每一步,我們均可以選擇空集,表示當(dāng)前構(gòu)造子集結(jié)束.dfs(true);}public int numTilePossibilities(String tiles) {//統(tǒng)計(jì)字符串中各字符數(shù)量for(int i = 0; i < tiles.length(); i++){char c = tiles.charAt(i);if(map.containsKey(c))map.put(c, map.get(c)+1);elsemap.put(c, 1);}//由于第一步不能選擇空集,因此第一步單獨(dú)考慮for(char c: map.keySet()){map.put(c, map.get(c)-1);dfs(false);map.put(c, map.get(c)+1);}return totalNum;} }

更新:

在參考其他人關(guān)于此題的題解后,發(fā)現(xiàn)我最初的思路很不是很簡(jiǎn)潔,存在很多可以優(yōu)化的地方.
1.首先由于原始字符串僅有大寫字符組成,因此我們可是使用整數(shù)數(shù)組保存每一個(gè)字符出現(xiàn)的次數(shù)來(lái)代替代碼中的HashMap結(jié)構(gòu).經(jīng)對(duì)比,使用整數(shù)數(shù)組能夠大幅減少程序執(zhí)行時(shí)間.
2.其次,回溯的思路可以重新設(shè)計(jì).我們每一步的可選集合為所有值不為0的鍵,在選完當(dāng)前值后,我們可以終止選擇,此時(shí)總的方案數(shù)加1,我們也可以繼續(xù)進(jìn)行下一個(gè)字符的選擇,此時(shí)我們遞歸調(diào)用,將當(dāng)前選中鍵的值減1,在遞歸退出后,將該鍵對(duì)應(yīng)的值加1.每次遞歸調(diào)用的結(jié)果為當(dāng)前剩余字符中可能的選擇結(jié)果.如果當(dāng)前剩余字符為空,則返回0.

class Solution {private int dfs(int[] charNum){int res = 0;for(int i = 0; i < charNum.length; i++){if(charNum[i] != 0){res++;charNum[i]--;res += dfs(charNum);charNum[i]++;}}return res;}public int numTilePossibilities(String tiles) {int[] charNum = new int[26];//統(tǒng)計(jì)字符串中各字符數(shù)量for(int i = 0; i < tiles.length(); i++){charNum[tiles.charAt(i)-'A']++;}return dfs(charNum);} }

總結(jié)

以上是生活随笔為你收集整理的leetcode:活字印刷的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。