【刷穿 LeetCode】6. Z 字形變換(中等)

點(diǎn)擊 這里 可以查看更多算法面試相關(guān)內(nèi)容~

題目描述

將一個(gè)給定字符串 s 根據(jù)給定的行數(shù) numRows 簿废,以從上往下、從左到右進(jìn)行 Z 字形排列。

比如輸入字符串為 "PAYPALISHIRING" 行數(shù)為 3 時(shí),排列如下:

P   A   H   N
A P L S I I G
Y   I   R

之后,你的輸出需要從左往右逐行讀取层释,產(chǎn)生出一個(gè)新的字符串,比如:"PAHNAPLSIIGYIR"

請(qǐng)你實(shí)現(xiàn)這個(gè)將字符串進(jìn)行指定行數(shù)變換的函數(shù):

string convert(string s, int numRows);

示例 1:

輸入:s = "PAYPALISHIRING", numRows = 3 輸出:"PAHNAPLSIIGYIR"

示例 2:

輸入:s = "PAYPALISHIRING", numRows = 輸出:"PINALSIGYAHRPI"

解釋:

P     I    N
A   L S  I G
Y A   H R
P     I

示例 3:

輸入:s = "A", numRows = 1 輸出:"A"

提示:

  • 1 <= s.length <= 1000
  • s 由英文字母(小寫(xiě)和大寫(xiě))甩恼、',''.' 組成
  • 1 <= numRows <= 1000

直觀規(guī)律解法

本題可以當(dāng)成模擬題來(lái)做。

對(duì)需要打印的行 i 進(jìn)行遍歷沉颂,每一行的第一個(gè)字符可以直接確定:原字符開(kāi)頭的第 i 個(gè)字符条摸。

然后計(jì)算出每行下一個(gè)字符的偏移量,這里需要分情況討論:

  • 對(duì)于第一行和最后一行:偏移量固定铸屉,不隨著 Z 的方向改變

  • 對(duì)于其他行:偏移量隨著 Z 的方向發(fā)生變化

class Solution {
    public String convert(String s, int r) {
        int n = s.length();
        if (n == 1 || r == 1) return s;

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < r; i++) {
            if (i == 0 || i == r - 1) {
                int j = i;
                int rowOffset = (r - 1) * 2 - 1;
                while (j < n) {
                    sb.append(s.charAt(j));
                    j += rowOffset + 1;
                }
            } else {
                int j = i;

                int topRow = i;
                int topOffset = topRow * 2 - 1;

                int bottomRow = r - i - 1;
                int bottomOffset = bottomRow * 2 - 1;

                boolean flag = true;
                while (j < n) {
                    sb.append(s.charAt(j));
                    j += flag ? bottomOffset + 1 : topOffset + 1;
                    flag = !flag;
                }
            }
        }
        return sb.toString();
    }
}

時(shí)間復(fù)雜度:分別對(duì) s 中的每個(gè)字符進(jìn)行打印钉蒲。復(fù)雜度為 O(n)

空間復(fù)雜度:O(1)


數(shù)學(xué)規(guī)律解法

在平時(shí)的練習(xí)中,對(duì)于這種找規(guī)律的題彻坛,當(dāng)我們使用直觀的思路推理出一個(gè)解法之后顷啼,可以嘗試從數(shù)學(xué)的角度上去分析。

例如本題昌屉,我們可以不失一般性的將規(guī)律推導(dǎo)為「首項(xiàng)」和「公差公式」钙蒙。

這通常能夠有效減少一些判斷。

分情況討論:

  • 對(duì)于第一行和最后一行:公差為 2 * (n ? 1) 的等差數(shù)列间驮,首項(xiàng)是 i

  • 對(duì)于其他行:兩個(gè)公差為 2 * (n ? 1) 的等差數(shù)列交替排列躬厌,首項(xiàng)分別是 i2 * n ? i ? 2

class Solution {
    public String convert(String s, int r) {
        int n = s.length();
        if (n == 1 || r == 1) return s;

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < r; i++) {
            if (i == 0 || i == r - 1) {
                int pos = i;
                int offset = 2 * (r - 1);
                while (pos < n) {
                    sb.append(s.charAt(pos));
                    pos += offset;
                }
            } else {
                int pos1 = i, pos2 = 2 * r - i - 2;
                int offset = 2 * (r - 1);
                while (pos1 < n || pos2 < n) {
                    if (pos1 < n) {
                        sb.append(s.charAt(pos1));
                        pos1 += offset;
                    }
                    if (pos2 < n) {
                        sb.append(s.charAt(pos2));
                        pos2 += offset;
                    }
                }
            }
        }
        return sb.toString();
    }
}

時(shí)間復(fù)雜度:分別對(duì) s 中的每個(gè)字符進(jìn)行打印。復(fù)雜度為 O(n)

空間復(fù)雜度:O(1)


總結(jié)

這種”找規(guī)律“的模擬題竞帽,和小學(xué)奧數(shù)題十分類似烤咧。要提高自己的做題水平偏陪,需要堅(jiān)持兩個(gè)方向:

  1. 自己多在紙上畫(huà)圖找規(guī)律,這種題沒(méi)有什么通用解法

  2. 多做題煮嫌,盡量對(duì)每種”規(guī)律“都有所接觸


最后

這是我們「刷穿 LeetCode」系列文章的第 No.6 篇笛谦,系列開(kāi)始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道題目昌阿,部分是有鎖題饥脑,我們將先將所有不帶鎖的題目刷完。

在這個(gè)系列文章里面懦冰,除了講解解題思路以外灶轰,還會(huì)盡可能給出最為簡(jiǎn)潔的代碼。如果涉及通解還會(huì)相應(yīng)的代碼模板刷钢。

由于 LeetCode 的題目隨著周賽 & 雙周賽不斷增加笋颤,為了方便我們統(tǒng)計(jì)進(jìn)度,我們將按照系列起始時(shí)的總題數(shù)作為分母内地,完成的題目作為分子伴澄,進(jìn)行進(jìn)度計(jì)算。當(dāng)前進(jìn)度為 6/1916 阱缓。

為了方便各位同學(xué)能夠電腦上進(jìn)行調(diào)試和提交代碼非凌,我建立了相關(guān)的倉(cāng)庫(kù):Github 地址 & Gitee 地址

在倉(cāng)庫(kù)地址里荆针,你可以看到系列文章的題解鏈接敞嗡、系列文章的相應(yīng)代碼、LeetCode 原題鏈接和一些其他的優(yōu)選題解航背。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末喉悴,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子玖媚,更是在濱河造成了極大的恐慌箕肃,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,695評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件最盅,死亡現(xiàn)場(chǎng)離奇詭異突雪,居然都是意外死亡起惕,警方通過(guò)查閱死者的電腦和手機(jī)涡贱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)惹想,“玉大人问词,你說(shuō)我怎么就攤上這事∴至唬” “怎么了激挪?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,130評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵辰狡,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我垄分,道長(zhǎng)宛篇,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,648評(píng)論 1 297
  • 正文 為了忘掉前任薄湿,我火速辦了婚禮叫倍,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘豺瘤。我一直安慰自己吆倦,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布坐求。 她就那樣靜靜地躺著蚕泽,像睡著了一般。 火紅的嫁衣襯著肌膚如雪桥嗤。 梳的紋絲不亂的頭發(fā)上须妻,一...
    開(kāi)封第一講書(shū)人閱讀 52,268評(píng)論 1 309
  • 那天,我揣著相機(jī)與錄音砸逊,去河邊找鬼璧南。 笑死,一個(gè)胖子當(dāng)著我的面吹牛师逸,可吹牛的內(nèi)容都是我干的司倚。 我是一名探鬼主播,決...
    沈念sama閱讀 40,835評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼篓像,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼动知!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起员辩,我...
    開(kāi)封第一講書(shū)人閱讀 39,740評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤盒粮,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后奠滑,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體丹皱,經(jīng)...
    沈念sama閱讀 46,286評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評(píng)論 3 340
  • 正文 我和宋清朗相戀三年宋税,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了摊崭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,505評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡杰赛,死狀恐怖呢簸,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤根时,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布瘦赫,位于F島的核電站,受9級(jí)特大地震影響蛤迎,放射性物質(zhì)發(fā)生泄漏确虱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評(píng)論 3 333
  • 文/蒙蒙 一替裆、第九天 我趴在偏房一處隱蔽的房頂上張望蝉娜。 院中可真熱鬧,春花似錦扎唾、人聲如沸召川。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,357評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)荧呐。三九已至,卻和暖如春纸镊,著一層夾襖步出監(jiān)牢的瞬間倍阐,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,466評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工逗威, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留峰搪,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,921評(píng)論 3 376
  • 正文 我出身青樓凯旭,卻偏偏與公主長(zhǎng)得像概耻,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子罐呼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評(píng)論 2 359

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