算法:?jiǎn)卧~縮寫

原題單詞縮寫

給出一組 n 個(gè)不同的非空字符串赎线,您需要按以下規(guī)則為每個(gè)單詞生成 最小 的縮寫。

  • 從第一個(gè)字符開始糊饱,然后加上中間縮寫掉的字符的長(zhǎng)度垂寥,后跟最后一個(gè)字符。
  • 如果有沖突另锋,就是多個(gè)單詞共享相同的縮寫滞项,使用較長(zhǎng)的前綴,而不是僅使用第一個(gè)字符夭坪,直到使單詞的縮寫的映射變?yōu)槲ㄒ弧?換句話說蓖扑,最終得到的縮寫不能映射到多個(gè)原始單詞。
  • 如果縮寫不會(huì)使單詞更短台舱,則不進(jìn)行縮寫律杠,保持原樣。

審題

  1. 首先這題的有個(gè)地方說得不清楚竞惋,就是解決沖突的方式柜去。比如iabcx和idefx沖突了,因?yàn)榭s寫都是i3x,這時(shí)需要把這兩個(gè)都加長(zhǎng)前綴拆宛,變成ia2x和id2x嗓奢。重點(diǎn)在于兩者都變化。應(yīng)用到整個(gè)集合里浑厚,當(dāng)有其他單詞和你沖突時(shí)股耽,你就要增大前綴,知道沒有單詞和你沖突钳幅。
  2. 我看了下題目的標(biāo)簽物蝙,里有個(gè)排序,順著這個(gè)思路想了下:
  • 只有后綴相同的單詞之前會(huì)可能沖突敢艰,因?yàn)楹缶Y一定保留

  • 只有長(zhǎng)度相同的會(huì)沖突诬乞。證明:如果長(zhǎng)度不同的單詞縮寫到長(zhǎng)度相同,那么縮寫掉部分的長(zhǎng)度肯定不同钠导,那么中間的數(shù)字肯定不同震嫉,那么這兩個(gè)縮寫肯定不同,不會(huì)沖突牡属。

??所以只有長(zhǎng)度相同且后綴相同的單詞才會(huì)沖突票堵,所以把這些可能沖突的分到一個(gè)組里。

  1. 經(jīng)過2的處理逮栅,同一個(gè)組里悴势,都是有沖突隱患的單詞窗宇。對(duì)于某一個(gè)單詞,要保留多長(zhǎng)的前綴才可以呢瞳浦?它和組內(nèi)的其他單詞比較共同前綴,假如最長(zhǎng)共同前綴為k,那么它就保留到k+1,因?yàn)榈絢+1的這一段废士,所有其他的都會(huì)跟它呈現(xiàn)出不同叫潦。如果直接照著這個(gè)直接實(shí)現(xiàn),復(fù)雜度是O(n^2),n是組內(nèi)的單詞個(gè)數(shù)官硝,有沒有辦法直接找到最長(zhǎng)共同前綴呢矗蕊?直接使用字符串的排序,字符串本身的比較方法是從前往后逐個(gè)比較字符氢架,所以具有更多共同前綴的單詞會(huì)貼到一起傻咖。
  2. 證明如下:

??假設(shè)排序后單詞k和k-1的共同前綴長(zhǎng)度是x,單詞k和k+1的共同長(zhǎng)度是y, 如果最長(zhǎng)共同前綴不是x或y,那么存在一個(gè)單詞t,它不在k的兩邊岖研,且共同前綴z滿足:z>x卿操,z>y。

??單詞k+1在k的后面孙援,且共同前綴是y,說明:k+1[y+1]>k[y+1];同理對(duì)于k-1有:k-1[x+1]<k[x+1]害淤。而z>x且z>y,那么這兩個(gè)式子對(duì)于t也是成立的,也就是在排序后t會(huì)在k-1和k+1之間拓售,而這時(shí)不可能的窥摄,所以出現(xiàn)錯(cuò)誤假設(shè)不成立,不存在這樣的t础淤。

??簡(jiǎn)單說崭放,公共前綴越長(zhǎng),排序后越靠近鸽凶。所以每個(gè)單詞只需要取左右相鄰單詞的共同前綴作為參考即可币砂。

代碼:

//對(duì)單詞排序,按長(zhǎng)度玻侥、后綴和單詞本身的先后順序
//這樣長(zhǎng)度相同道伟、后綴相同的單詞會(huì)分到一起
bool wordPairCmp(pair<string, int>& wp1, pair<string, int> &wp2){
    int result = (int)wp1.first.length()-(int)wp2.first.length();
    if (result!=0) return result<0;
    result = wp1.first.back()-wp2.first.back();
    if (result!=0) return result<0;
    
    return wp1.first.compare(wp2.first)<0;
}

//求共同前綴的長(zhǎng)度
inline int prefixLapCount(string &s1, string &s2){
    int c = 0;
    while (s1[c] == s2[c]) {
        c++;
    }
    return c;
}

//把一個(gè)單詞按指定前綴長(zhǎng)度縮寫
inline void wordAbb(string &originalWord, int prefixCount){
    int len = (int)originalWord.length();
    int cut = len-prefixCount-1;
    if (cut<=1) {
        return;
    }
    
    int destLen = prefixCount+1+log10(cut)+1;
    int preIdx = len-cut-2;
    string abb(destLen,' ');
    
    for (int i = 0; i<=preIdx; i++) {
        abb[i] = originalWord[i];
    }
    abb[destLen-1] = originalWord.back();
    
    //中間縮寫的數(shù)字部分,沒有使用atoi等方法而是直接實(shí)現(xiàn)使碾,效率會(huì)快很對(duì)
    for (int i = destLen-2; i>preIdx; i--) {
        abb[i] = cut%10+'0';
        cut = cut/10;
    }
    
    originalWord = abb;
}

vector<string> wordsAbbreviation(vector<string> &dict) {
    
    //使用pair的原因是為了記錄單詞在原數(shù)組里的索引位置蜜徽,這樣排序后,還可以再重置到輸入時(shí)的順序
    vector<pair<string, int>> wordPairs;
    int i = 0;
    for (auto &w : dict){
        wordPairs.push_back({w,i});
        i++;
    }
    sort(wordPairs.begin(), wordPairs.end(), wordPairCmp);
    
    int size = (int)wordPairs.size();
    int preLapCount = 0; //和前一個(gè)重疊的字符個(gè)數(shù)
    for (int i = 0; i<size; i++) {
        
        int nextLapCount = 0;
        //因?yàn)闆]有使用分組票摇,即沒有用多維數(shù)組拘鞋,而是單個(gè)數(shù)組,所以需要做前后判定矢门,長(zhǎng)度不同或者后綴不同盆色,則共同前綴就不考慮了灰蛙,直接是0.
        //這里會(huì)影響效率,因?yàn)榇蟛糠直容^都是無意義的或者說跟排序的工作有重復(fù)
        if (i<size-1 &&
            wordPairs[i].first.length() == wordPairs[i+1].first.length() &&
            wordPairs[i].first.back() == wordPairs[i+1].first.back()) {
            nextLapCount = prefixLapCount(wordPairs[i].first, wordPairs[i+1].first);
        }
        
        wordAbb(wordPairs[i].first, max(preLapCount, nextLapCount)+1);
        preLapCount = nextLapCount;
    }
    
    for (auto &p : wordPairs){
        dict[p.second] = p.first;
    }
    
    return dict;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末隔躲,一起剝皮案震驚了整個(gè)濱河市摩梧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌宣旱,老刑警劉巖仅父,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異浑吟,居然都是意外死亡笙纤,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門组力,熙熙樓的掌柜王于貴愁眉苦臉地迎上來省容,“玉大人,你說我怎么就攤上這事燎字⌒冉罚” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵候衍,是天一觀的道長(zhǎng)寞酿。 經(jīng)常有香客問我,道長(zhǎng)脱柱,這世上最難降的妖魔是什么伐弹? 我笑而不...
    開封第一講書人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮榨为,結(jié)果婚禮上惨好,老公的妹妹穿的比我還像新娘。我一直安慰自己随闺,他們只是感情好日川,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著矩乐,像睡著了一般龄句。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上散罕,一...
    開封第一講書人閱讀 51,708評(píng)論 1 305
  • 那天分歇,我揣著相機(jī)與錄音,去河邊找鬼欧漱。 笑死职抡,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的误甚。 我是一名探鬼主播缚甩,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼谱净,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了擅威?” 一聲冷哼從身側(cè)響起壕探,我...
    開封第一講書人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎郊丛,沒想到半個(gè)月后李请,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宾袜,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年捻艳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡结蟋,死狀恐怖脱惰,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情董栽,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站杉畜,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏衷恭。R本人自食惡果不足惜此叠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望随珠。 院中可真熱鬧灭袁,春花似錦、人聲如沸窗看。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽显沈。三九已至软瞎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間拉讯,已是汗流浹背涤浇。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留魔慷,地道東北人芙代。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像盖彭,于是被迫代替她去往敵國(guó)和親纹烹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子页滚,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 前言 最先接觸編程的知識(shí)是在大學(xué)里面裹驰,大學(xué)里面學(xué)了一些基礎(chǔ)的知識(shí),c語言片挂,java語言幻林,單片機(jī)的匯編語言等;大學(xué)畢...
    oceanfive閱讀 3,087評(píng)論 0 7
  • 在C語言中,五種基本數(shù)據(jù)類型存儲(chǔ)空間長(zhǎng)度的排列順序是: A)char B)char=int<=float C)ch...
    夏天再來閱讀 3,345評(píng)論 0 2
  • 官網(wǎng) 中文版本 好的網(wǎng)站 Content-type: text/htmlBASH Section: User ...
    不排版閱讀 4,383評(píng)論 0 5
  • 文|月半貓 每一個(gè)女生心中都有一個(gè)公主夢(mèng)音念,希望自己的另一半能像王子一般沪饺,優(yōu)秀、英俊闷愤,對(duì)愛情忠貞不渝整葡。可現(xiàn)實(shí)生活中讥脐,...
    一條流浪的貓閱讀 123評(píng)論 0 0
  • 有修養(yǎng)的人遭居,既不樂觀也不悲觀,而是客觀旬渠。他們不相信世界上有絕對(duì)三觀相合俱萍、趣味相投的人,就像不相信有完全相同的兩片樹...
    嬉笑怒罵皆生活閱讀 181評(píng)論 0 0