目錄
- LeetCode中國站原文
- 原始題目
- 題目描述
- 示例 1:
- 示例 2:
- 示例 3:
- 提示:
- 講解
- 化繁為簡:如何優雅地“盤”邏輯判斷題
- 第一部分:算法思想 —— “清單核對”與“一票否決”
- 第二部分:代碼實現 —— 清晰的邏輯翻譯
- 實現一:常規判斷邏輯
- 實現二:使用正則表達式(一行代碼的“炫技”)
- 第三部分:總結
LeetCode中國站原文
https://leetcode.cn/problems/valid-word/
原始題目
題目描述
有效單詞 需要滿足以下幾個條件:
- 至少 包含 3 個字符。
- 由數字 0-9 和英文大小寫字母組成。(不必包含所有這類字符。)
- 至少 包含一個 元音字母 。
- 至少 包含一個 輔音字母 。
給你一個字符串 word
。如果 word
是一個有效單詞,則返回 true
,否則返回 false
。
注意:
'a'
、'e'
、'i'
、'o'
、'u'
及其大寫形式都屬于 元音字母 。- 英文中的 輔音字母 是指那些除元音字母之外的字母。
示例 1:
輸入:word = "234Adas"
輸出:true
解釋:這個單詞滿足所有條件。
示例 2:
輸入:word = "b3"
輸出:false
解釋:這個單詞的長度少于 3 且沒有包含元音字母。
示例 3:
輸入:word = "a3$e"
輸出:false
解釋:這個單詞包含了 '$' 字符且沒有包含輔音字母。
提示:
1 <= word.length <= 20
講解
化繁為簡:如何優雅地“盤”邏輯判斷題
大家好!今天我們來解決一道非常適合新手入門的題目:LeetCode 3136. 有效單詞。
這道題沒有炫酷的算法,也不需要復雜的數據結構。它就像一個“邏輯清單”,考驗的是我們如何把一系列規則,清晰、準確地翻譯成代碼。這類問題在實際工作中非常常見,比如校驗用戶輸入的密碼、驗證表單字段等。讓我們來看看如何優雅地完成這項任務。
第一部分:算法思想 —— “清單核對”與“一票否決”
解決這類“多條件判斷”問題,最好的方法就是“清單核對法”。我們可以把題目中的所有要求,想象成一張通關清單,我們的 word
字符串需要逐項檢查,全部打上勾才能通關。
通關清單:
- 長度審查:
word
的長度是否>= 3
? - 成分審查:
word
中的每一個字符,是否都是字母或數字? - 元音指標:
word
中是否至少有一個元音字母? - 輔音指標:
word
中是否至少有一個輔音字母?
核心策略:“一票否決制”
在核對清單時,最有效的策略是“一票否決”。只要在檢查過程中發現任何一項不滿足,我們就可以立刻得出結論:這個 word
無效,直接返回 false
,后面的檢查就不用再做了。這可以避免不必要的計算。
這個流程圖清晰地展示了我們的策略:
- 先處理硬性條件:首先檢查長度和字符合法性。這兩項是“全局”的,只要有一個字符不滿足,整個單詞就作廢。
- 再統計指標:在遍歷檢查字符合法性的同時,我們可以順便完成“元音”和“輔音”的統計任務。用兩個布爾變量
hasVowel
和hasConsonant
作為標記,一旦找到,就把它設為true
。 - 最后匯總:所有字符都遍歷完后,如果程序還沒有提前退出,說明長度和成分都合格了。這時,我們只需要檢查
hasVowel
和hasConsonant
這兩個標記是否都為true
,就能做出最終的裁決。
第二部分:代碼實現 —— 清晰的邏輯翻譯
現在,我們把“清單核對”和“一票否決”的策略翻譯成代碼。
實現一:常規判斷邏輯
這是最直接、最易于理解的實現方式。
class Solution {/*** 校驗一個字符串是否為“有效單詞”。* @param word 待校驗的字符串。* @return 如果有效,返回 true;否則返回 false。*/public boolean isValid(String word) {// 條件1: 長度審查if (word.length() < 3) {return false;}// 準備兩個標記,用于統計元音和輔音指標boolean hasVowel = false;boolean hasConsonant = false;// 開始遍歷,同時進行“成分審查”和“指標統計”for (char ch : word.toCharArray()) {// 條件2: 成分審查if (!Character.isLetterOrDigit(ch)) {return false; // 一票否-決:包含非法字符}// 判斷字符類型,并更新指標if (Character.isLetter(ch)) {if ("aeiouAEIOU".indexOf(ch) != -1) {hasVowel = true; // 找到了元音} else {hasConsonant = true; // 找到了輔音}}}// 最終裁決:檢查兩個核心指標是否都已達成return hasVowel && hasConsonant;}
}
代碼解讀:
Character.isLetterOrDigit(ch)
:Java 內置的函數,非常方便地判斷一個字符是否為字母或數字。"aeiouAEIOU".indexOf(ch) != -1
:這是一個判斷元音的小技巧。我們把所有元音字母組成一個字符串,然后檢查當前字符ch
是否能在這個字符串里找到。如果能找到(indexOf
返回的不是-1
),那它就是元音。
實現二:使用正則表達式(一行代碼的“炫技”)
對于熟悉正則表達式的高手來說,可以用一行代碼解決這個問題。這種方法雖然簡潔,但在性能上通常不如直接遍歷,且可讀性對新手不友好,更適合作為一種思路擴展。
class Solution {public boolean isValid(String word) {// 正則表達式的含義:// (?=.*[aeiouAEIOU]) - 正向先行斷言:字符串中必須存在至少一個元音// (?=.*[bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ]) - 字符串中必須存在至少一個輔音// [a-zA-Z0-9]{3,} - 字符串本身必須由3個或以上的大小寫字母和數字組成return word.matches("(?i)(?=.*[aeiou])(?=.*[b-df-hj-np-tv-z])[a-z0-9]{3,}");}
}
注:第二種寫法為了簡潔,在輔音的判斷上使用了[b-df-hj-np-tv-z]
這種窮舉方式,并使用 (?i)
標志來忽略大小寫。這種寫法主要是為了展示正則表達式的強大能力,在實際面試中,第一種清晰的遍歷寫法通常更受青睞。
第三部分:總結
這道“有效單詞”題,是一次絕佳的編程基本功練習。它告訴我們:
- 拆解問題:面對一系列復雜規則,首先要把它們拆解成一個個清晰、獨立的小任務。
- 流程控制:使用“一票否決”可以有效提升代碼效率,避免不必要的計算。
- 善用工具:熟悉并使用語言內置的函數(如
Character.isLetterOrDigit
)可以讓代碼更簡潔、更健壯。