小小算法检诗,頻繁刺激-Palindrome Number

今天刷LeetCode匈仗,遇到一道簡單算法題,Palindrome Number逢慌,但解題過程比較有意思悠轩,借此文記錄下。

解析題目

問題描述: Determine whether an integer is a palindrome. Do this without extra space. 判斷一個int類型的數(shù)是否為回文數(shù)攻泼? 不使用額外空間火架。

關(guān)于什么是回文數(shù)?給個定義:正反方向輸出的值相等的數(shù)稱為回文數(shù)忙菠。 沒理解到的何鸡,可以去網(wǎng)上搜下。

舉例:1牛欢、1221骡男、11211等是回文數(shù);-1傍睹、0隔盛、12、123323等就不是回文數(shù)拾稳。

那什么是回文字符串呢吮炕?可以參考這篇文章【算法】Longest Palindromic Substring

分析思路

理解題目后熊赖,總共想到三個思路:

  • 按位比較: 1. 計算整數(shù)的位數(shù)(長度)来屠, 2. 從第一位和最后一位開始依次遞增和增減循環(huán)比較。
  • 反轉(zhuǎn)輸入int震鹉,與原數(shù)比較看是否相等俱笛。 之前有道題是:反轉(zhuǎn)一個int數(shù),其中需要考慮溢出問題传趾。
  • 轉(zhuǎn)成字符串迎膜,按位比較。 但題目限制不能占用額外內(nèi)存浆兰。

考慮使用第一種思路磕仅,這道題比較簡單珊豹,有了思路后,按說就可以編碼了榕订,但為了養(yǎng)成好習(xí)慣店茶,別著急編碼還是想下case情況先。我只想到兩個:1.負數(shù)不是回文數(shù)劫恒。 2. 考慮位數(shù)奇偶數(shù)情況贩幻。雖然少,過程不能省两嘴。

開始編碼丛楚,貼下我第一版代碼。

public boolean isPalindrome(int x) {
        if (x < 0) { // 負數(shù)情況
            return false;
        }
        final int originX = x;
        int bitCount = 1;
        // 算出有多少位(長度)
        while (x >= 10) {
            x /= 10;
            bitCount++;
        }

        int l = 0;
        int r = bitCount - 1;
        // 依次比較
        while (getBitNum(originX, bitCount, l) == getBitNum(originX, bitCount, r)) {
            l++;
            r--;
            if (l >= r) {
                return true;
            }
        }
        return false;
    }

    // 去取原數(shù)對應(yīng)位下標(biāo)的數(shù)值
    int getBitNum(int num, final int len, int index) {
        int temp = 1;
        while (len - index > 1) {
            temp *= 10;
            index++;
        }
        return (num / temp) % 10;
    }

LeetCode上類似白板編程憔辫,代碼比較齪趣些,請見諒。編寫完了自測case贰您,好都沒問題坏平,這么簡單那就提交吧,提交是通過了锦亦,但提示該算法擊敗了1.7%的其它用戶提交功茴,也就是說效率很差,墊底了孽亲。這樣怎么行呢,畢竟咋還是有追求的程序猿對吧展父。于是分析代碼返劲,其中三處循環(huán),還有嵌套栖茉;估算時間復(fù)雜度為:O(nlog10n)篮绿。* (ps:時間復(fù)雜度計算,不是很清楚吕漂,有知道的大神請留言指教亲配,謝謝。)

懷著焦慮的心情惶凝,點開了官方推薦解法頁面吼虎。看到一半苍鲜,哎呀思灰,這不是上文中我想到的第二條思路嗎,反轉(zhuǎn)int整數(shù)混滔。但官方建議只反轉(zhuǎn)int的一半洒疚,然后與剩下一半比較歹颓,如果相等則是回文數(shù)。這就完美避開了Integer.MAX_VALUE溢出問題油湖,不得不服巍扛。

想著先不看其代碼實現(xiàn),自己寫一下再說乏德,于是在之前基礎(chǔ)上改出了下面的代碼撤奸。

boolean isPalindromeNum(int x) {
        if (x < 0) {
            return false;
        }
        final int originX = x;
        int bitCount = 1;
        while (x >= 10) {
            x /= 10;
            bitCount++;
        }
        int index = 0;
        int halfNum = 0;
        final int halfLen = bitCount / 2;
        int tempX = originX;
        while (index < halfLen) {
            halfNum = halfNum * 10 + tempX % 10;
            tempX /= 10;
            index++;
        }
        // 判斷奇偶情況
        return halfNum == (bitCount % 2 == 0 ? tempX : tempX / 10);

提交跑起來,嗯快了不少鹅经,擊敗了48%寂呛,感覺不錯對吧。這會去看官方給出的C#代碼實現(xiàn)瘾晃,看完感覺受到一萬點傷害贷痪,吐血了。不說了蹦误,貼代碼劫拢。

    boolean isPalindromeNumOfficial(int x) {
        // Special cases:
        // As discussed above, when x < 0, x is not a palindrome.
        // Also if the last digit of the number is 0, in order to be a palindrome,
        // the first digit of the number also needs to be 0.
        // Only 0 satisfy this property.
        if (x < 0 || (x % 10 == 0 && x != 0)) {
            return false;
        }

        int revertedNumber = 0;
        while (x > revertedNumber) {
            revertedNumber = revertedNumber * 10 + x % 10;
            x /= 10;
        }

        // When the length is an odd number, we can get rid of the middle digit by revertedNumber/10
        // For example when the input is 12321, at the end of the while loop we get x = 12, revertedNumber = 123,
        // since the middle digit doesn't matter in palidrome(it will always equal to itself), we can simply get rid of it.
        return x == revertedNumber || x == revertedNumber / 10;
    }

注釋寫的很清楚了,主要有三點:1. 判斷尾數(shù)為0的情況 2. 取消判斷位數(shù)的邏輯 3. 聰明處理奇偶位數(shù)情況强胰。

小結(jié)

小小一道簡單的算法題舱沧,都能頻繁帶給你刺激,是不是很過癮偶洋。想想平時我們寫的代碼熟吏,是不是應(yīng)該翻出來再斟酌斟酌,哈哈哈玄窝。

最后貼下轉(zhuǎn)字符串思路實現(xiàn)的代碼牵寺。

// 轉(zhuǎn)字符串在比較 ,速度是很快的
    public boolean isPalindromeForString(int x) {
        String num = String.valueOf(x);
        if (num == null || num.length() == 0) return true;
        int start = 0, end = num.length() - 1;
        while (start < end) {
            if ((char) num.charAt(start) != (char) num.charAt(end)) return false;
            start++;
            end--;
        }
        return true;
    }

以上代碼均由Java實現(xiàn)恩脂,項目地址https://github.com/yangjiantao/DSAA帽氓。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市俩块,隨后出現(xiàn)的幾起案子黎休,更是在濱河造成了極大的恐慌,老刑警劉巖玉凯,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件势腮,死亡現(xiàn)場離奇詭異,居然都是意外死亡漫仆,警方通過查閱死者的電腦和手機嫉鲸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來歹啼,“玉大人玄渗,你說我怎么就攤上這事座菠。” “怎么了藤树?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵浴滴,是天一觀的道長。 經(jīng)常有香客問我岁钓,道長升略,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任屡限,我火速辦了婚禮品嚣,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘钧大。我一直安慰自己翰撑,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布啊央。 她就那樣靜靜地躺著眶诈,像睡著了一般。 火紅的嫁衣襯著肌膚如雪瓜饥。 梳的紋絲不亂的頭發(fā)上逝撬,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天,我揣著相機與錄音乓土,去河邊找鬼宪潮。 笑死,一個胖子當(dāng)著我的面吹牛趣苏,可吹牛的內(nèi)容都是我干的坎炼。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼拦键,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了檩淋?” 一聲冷哼從身側(cè)響起芬为,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蟀悦,沒想到半個月后媚朦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡日戈,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年询张,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片浙炼。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡份氧,死狀恐怖唯袄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蜗帜,我是刑警寧澤恋拷,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站厅缺,受9級特大地震影響蔬顾,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜湘捎,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一诀豁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧窥妇,春花似錦舷胜、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至纱新,卻和暖如春展氓,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背脸爱。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工遇汞, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人簿废。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓空入,卻偏偏與公主長得像,于是被迫代替她去往敵國和親族檬。 傳聞我的和親對象是個殘疾皇子歪赢,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,933評論 2 355

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