LeetCode 1704: Determine if String Halves Are Alike (Vowel Balance Counting)
LeetCode 1704StringCountingToday we solve LeetCode 1704 - Determine if String Halves Are Alike.
Source: https://leetcode.com/problems/determine-if-string-halves-are-alike/
English
Problem Summary
You are given an even-length string s. Split it into two equal halves and return true if both halves contain the same number of vowels; otherwise return false.
Key Insight
Only vowel counts matter. Scan left half and right half simultaneously and maintain a balance: +1 for a vowel in the left half, -1 for a vowel in the right half. Final balance 0 means the halves are alike.
Algorithm Steps
1) Build a vowel lookup set for both lowercase and uppercase vowels.
2) Let n = s.length(), half = n / 2.
3) For each i in [0, half): if s[i] is vowel, increment balance; if s[i+half] is vowel, decrement balance.
4) Return whether balance equals zero.
Complexity Analysis
Time: O(n).
Space: O(1) (fixed vowel set size).
Common Pitfalls
- Forgetting uppercase vowels like 'A', 'E'.
- Splitting at wrong index for even-length string.
- Counting all characters instead of vowels only.
Reference Implementations (Java / Go / C++ / Python / JavaScript)
class Solution {
public boolean halvesAreAlike(String s) {
String vowels = "aeiouAEIOU";
int n = s.length();
int half = n / 2;
int balance = 0;
for (int i = 0; i < half; i++) {
if (vowels.indexOf(s.charAt(i)) >= 0) balance++;
if (vowels.indexOf(s.charAt(i + half)) >= 0) balance--;
}
return balance == 0;
}
}func halvesAreAlike(s string) bool {
isVowel := func(c byte) bool {
switch c {
case 'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U':
return true
}
return false
}
n := len(s)
half := n / 2
balance := 0
for i := 0; i < half; i++ {
if isVowel(s[i]) {
balance++
}
if isVowel(s[i+half]) {
balance--
}
}
return balance == 0
}class Solution {
public:
bool isVowel(char c) {
switch (c) {
case 'a': case 'e': case 'i': case 'o': case 'u':
case 'A': case 'E': case 'I': case 'O': case 'U':
return true;
default:
return false;
}
}
bool halvesAreAlike(string s) {
int n = (int)s.size();
int half = n / 2;
int balance = 0;
for (int i = 0; i < half; ++i) {
if (isVowel(s[i])) balance++;
if (isVowel(s[i + half])) balance--;
}
return balance == 0;
}
};class Solution:
def halvesAreAlike(self, s: str) -> bool:
vowels = set("aeiouAEIOU")
n = len(s)
half = n // 2
balance = 0
for i in range(half):
if s[i] in vowels:
balance += 1
if s[i + half] in vowels:
balance -= 1
return balance == 0/**
* @param {string} s
* @return {boolean}
*/
var halvesAreAlike = function(s) {
const vowels = new Set(['a','e','i','o','u','A','E','I','O','U']);
const n = s.length;
const half = n >> 1;
let balance = 0;
for (let i = 0; i < half; i++) {
if (vowels.has(s[i])) balance++;
if (vowels.has(s[i + half])) balance--;
}
return balance === 0;
};中文
题目概述
给定一个长度为偶数的字符串 s,将其分成左右两半。若两半中元音字母数量相同,返回 true,否则返回 false。
核心思路
本题只关心“元音数量是否相等”。可以使用“平衡值”技巧:左半遇到元音 +1,右半遇到元音 -1。最终平衡值为 0 即表示两半元音数一致。
算法步骤
1)准备元音集合,包含大小写:a,e,i,o,u,A,E,I,O,U。
2)设 half = n / 2。
3)遍历 i = 0..half-1:若左半字符是元音则 balance++;若右半对应字符是元音则 balance--。
4)最后判断 balance == 0。
复杂度分析
时间复杂度:O(n)。
空间复杂度:O(1)(元音集合大小固定)。
常见陷阱
- 漏掉大写元音,导致统计错误。
- 分割点写错,没有严格按一半长度对应比较。
- 把所有字母都计数,而非仅统计元音。
参考实现(Java / Go / C++ / Python / JavaScript)
class Solution {
public boolean halvesAreAlike(String s) {
String vowels = "aeiouAEIOU";
int n = s.length();
int half = n / 2;
int balance = 0;
for (int i = 0; i < half; i++) {
if (vowels.indexOf(s.charAt(i)) >= 0) balance++;
if (vowels.indexOf(s.charAt(i + half)) >= 0) balance--;
}
return balance == 0;
}
}func halvesAreAlike(s string) bool {
isVowel := func(c byte) bool {
switch c {
case 'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U':
return true
}
return false
}
n := len(s)
half := n / 2
balance := 0
for i := 0; i < half; i++ {
if isVowel(s[i]) {
balance++
}
if isVowel(s[i+half]) {
balance--
}
}
return balance == 0
}class Solution {
public:
bool isVowel(char c) {
switch (c) {
case 'a': case 'e': case 'i': case 'o': case 'u':
case 'A': case 'E': case 'I': case 'O': case 'U':
return true;
default:
return false;
}
}
bool halvesAreAlike(string s) {
int n = (int)s.size();
int half = n / 2;
int balance = 0;
for (int i = 0; i < half; ++i) {
if (isVowel(s[i])) balance++;
if (isVowel(s[i + half])) balance--;
}
return balance == 0;
}
};class Solution:
def halvesAreAlike(self, s: str) -> bool:
vowels = set("aeiouAEIOU")
n = len(s)
half = n // 2
balance = 0
for i in range(half):
if s[i] in vowels:
balance += 1
if s[i + half] in vowels:
balance -= 1
return balance == 0/**
* @param {string} s
* @return {boolean}
*/
var halvesAreAlike = function(s) {
const vowels = new Set(['a','e','i','o','u','A','E','I','O','U']);
const n = s.length;
const half = n >> 1;
let balance = 0;
for (let i = 0; i < half; i++) {
if (vowels.has(s[i])) balance++;
if (vowels.has(s[i + half])) balance--;
}
return balance === 0;
};
Comments