每天 3 分鐘,走上演算法的逆襲之路。每日一道 leetcode 前文合集
github:
gitee:
給定乙個字串,驗證它是否是回文串,只考慮字母和數字字元,可以忽略字母的大小寫。
說明:本題中,我們將空字串定義為有效的回文串。
示例 1:
輸入: "a man, a plan, a canal: panama"
輸出: true
示例 2:
輸入: "race a car"
輸出: false
這種求回文數的題前面出現過,主體思路有兩種:
先寫自己的答案,這個答案太 2b 了,我就不貼執行效率了。
public boolean ispalindrome(string s) else
}return flag;
}
我在最開始,對原始字串先做去除空格,轉小寫,然後通過正則把其中所有有效的字元全都匹配出來。
這樣乙個正常字串被這麼處理完成後就成這樣了:
# 處理前
damosel, a poem? a carol? or a cameo pale? (so mad!)
# 處理後
damoselapoemacaroloracameopalesomad
然後再使用雙指標進行判斷,這個字串是否是回文串。
這麼看好像執行效率還可以,實際上正則匹配是乙個相當耗時的操作,還是乖乖去翻答案吧。
先放**:
public boolean ispalindrome_1(string s)
}int n = sgood.length();
int left = 0, right = n - 1;
while (left < right)
++left;
--right;
}return true;
}
答案上這個解析是使用了 jdk 提供的character.isletterordigit()
來判斷輸入的字元是否是字母或者數字,這個方法應該比我剛才的正則要快,下面的那段迴圈其實大同小異,都是從兩邊判斷字元是否相等。
這個方案好像也挺慢的,它還是要先迴圈一次,使用整理過後的字串進行的判斷,那麼肯定可以直接在原字串上進行判斷,這樣可以減少迴圈的次數。
這個方案就是沒有預先處理字串,直接在一次迴圈中進行處理,當當前指向的不是有效字元的時候,進行移動指標++left
和--right
操作。
移動完指標以後進行判斷,看兩個字元是否相等,如果不相等就直接返回 false ,相等的話接著移動一位指標。
這個耗時還有 3ms ,那有沒有耗時更短的方案,我在提交的記錄中找到了某位不知名的大神的解題方案。
上面這種方案看起來好像已經沒有優化的空間了,那怎麼還能縮短耗時。
優化character.isletterordigit()
這個方法,這個方法的耗時還是有點高的,實際上可以通過 ascii 直接進行判斷當前是否為有效字元。
接著在判斷的時候使用tolowercase()
這個方法來轉小寫,而是通過 ascii 的方式進行轉換。
遇到大小寫字母的時候,小寫字母比其對應的大寫字母的 ascii 碼大 32 。
所以如果遇到了大寫字母,先加上 32 ,然後再減去 'a' ,就知道其相對於 'a' 的位置了,這個值肯定是小於 32 的,對 32 取餘沒啥影響。
如果遇到小寫字母,雖然加上了 32 ,但是最後對 32 取餘了,多加的 32 也就沒了,所以還是能得到其相對於 'a' 的正確位置。
大神的思路果然是常人不能企及,乙個詞來形容下,牛13!!!
下面是**:
今天這道題可以總結乙個小套路,遇到字元判斷的時候,最高效的方案是使用 ascii 進行判斷,大小寫字母中間 ascii 值相差 32 ,巧用這個差值,可以快速判斷大小寫字母。
Leetcode 每日一道
如果不出意外每天會寫一道演算法題的部落格。如果題目簡單,就一天發布一道。如果題目比較難。我會2 3天發一道演算法的題目。今天寫的這道題目比較簡單。題目如下 解法我是用c 寫的。我的解法的大致想法是 先把需要轉換的矩陣直接轉換成一維的陣列,然後再根據要求把一維中的元素全部截為以c個元素為一組的vect...
每日一道leetcode 最大括號深度
有效括號字串 定義 對於每個左括號,都能找到與之對應的右括號,反之亦然。詳情參見題末 有效括號字串 部分。巢狀深度 depth 定義 即有效括號字串巢狀的層數,depth a 表示有效括號字串 a 的巢狀深度。詳情參見題末 巢狀深度 部分。有效括號字串型別與對應的巢狀深度計算方法如下圖所示 給你乙個...
每日一道 LeetCode 11 外觀數列
每天 3 分鐘,走上演算法的逆襲之路。每日一道 leetcode 前文合集 github gitee 給定乙個正整數 n 1 n 30 輸出外觀數列的第 n 項。注意 整數序列中的每一項將表示為乙個字串。外觀數列 是乙個整數序列,從數字 1 開始,序列中的每一項都是對前一項的描述。前五項如下 1.1...