Determine if String Halves Are Alike solution and explanation
9 more videos on this problem
Determine if String Halves Are Alike | Live Coding with Explanation | Leetcode - 1704Algorithms Made Easy · 3:01 · 2K views
Leetcode | 1704. Determine if String Halves Are Alike | Easy | Java SolutionDeveloper Docs · 4:39 · 487 views
Determine if String Halves Are Alike | LeetCode 1704 | Coders CampCoders Camp · 3:59 · 444 views
Daily Leetcode #975: Dec 01, 2022 - 1704. Determine if String Halves Are AlikeProgramming Live with Larry · 3:54 · 409 views
1704. Determine if String Halves Are Alike (Leetcode Easy)Programming Live with Larry · 3:36 · 302 views
1704. Determine if String Halves are Alike | Leetcode | EasyCodeRebel · 8:20 · 164 views
1704. Determine if String Halves Are Alike | JavaScript | LeetCode Daily Challenge | DetailedLeetCodeWithMonu · 4:49 · 137 views
Leetcode 1704. Determine if String Halves Are AlikeAlgorithms Casts · 4:50 · 132 views
LeetCode 1704 Determine if String Halves Are AlikeThe Code Architect · 5:15 · 121 views
How to Solve "1704 Determine if String Halves Are Alike" on LeetCode - JavascriptBecoming A Better Dev (with David) · 7:17 · 108 views
The problem
You are given a string s of even length. Split this string into two halves of equal lengths, and let a be the first half and b be the second half.
Two strings are alike if they have the same number of vowels ('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'). Notice that s contains uppercase and lowercase letters.
Return true if a and b are alike. Otherwise, return false.
Example 1:
Input: s = "book" Output: true Explanation: a = "bo" and b = "ok". a has 1 vowel and b has 1 vowel. Therefore, they are alike.
Example 2:
Input: s = "textbook" Output: false Explanation: a = "text" and b = "book". a has 1 vowel whereas b has 2. Therefore, they are not alike. Notice that the vowel o is counted twice.
Constraints:
2 <= s.length <= 1000s.lengthis even.sconsists of uppercase and lowercase letters.
Approach overview
Problem Overview: You receive a string s with even length. Split it into two halves and determine whether both halves contain the same number of vowels. Vowels include a, e, i, o, u in both lowercase and uppercase. The task reduces to counting vowels in each half and comparing the totals.
Approach 1: Character Counting via Direct Comparison (O(n) time, O(1) space)
Traverse the string and count vowels separately for the first and second halves. Compute the midpoint using mid = n / 2, then iterate from 0 → mid-1 to count vowels in the first half and from mid → n-1 for the second half. Each character is checked against a small set of vowels using direct comparison or membership lookup. Since the vowel set is constant in size, every check runs in constant time, giving a total time complexity of O(n) and constant auxiliary space O(1). This approach is simple and very readable, making it ideal when clarity matters more than minimizing passes.
Approach 2: Two-Pointer Vowel Count Approach (O(n) time, O(1) space)
Use two pointers that move through the two halves simultaneously. One pointer starts at the beginning of the string, and the other starts at the midpoint. On each iteration, check whether each pointer points to a vowel and update two counters (or maintain a single difference counter). This processes both halves in a single loop while performing constant-time vowel checks using a predefined set like "aeiouAEIOU". The algorithm still scans each character once, so the time complexity remains O(n) with O(1) extra space. The advantage is fewer loops and a symmetric structure that mirrors the two halves being compared.
Both strategies rely on fundamental string traversal and simple counting logic. No additional data structures are required because the problem only tracks a small number of counters and checks membership in a constant-size vowel set.
Recommended for interviews: The two-pointer vowel counting approach is typically preferred. It demonstrates clean iteration logic and efficient comparison of both halves in a single pass. Showing the direct counting version first can communicate your understanding quickly, while the two-pointer refinement shows awareness of cleaner traversal patterns often expected in string problems.
Approach 1: Two-Pointer Vowel Count Approach
This method involves using two pointers to count the number of vowels in each half of the string.
By using a set to identify vowels, iterate through each character in both halves. Compare the final counts for equality to determine if they are alike.
def halvesAreAlike(s: str) -> bool:
vowels = set('aeiouAEIOU')
n = len(s) // 2
count1 = sum(1 for i in range(n) if s[i] in vowels)
count2 = sum(1 for i in range(n, len(s)) if s[i] in vowels)
return count1 == count2import java.util.Set;
public class Solution {
public boolean halvesAreAlike(String s) {
Set<Character> vowels = Set.of('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U');
int n = s.length() / 2;
int count1 = 0, count2 = 0;
for (int i = 0; i < n; i++) {
if (vowels.contains(s.charAt(i))) count1++;
if (vowels.contains(s.charAt(i + n))) count2++;
}
return count1 == count2;
}
}#include <string>
#include <unordered_set>
using namespace std;
bool halvesAreAlike(string s) {
unordered_set<char> vowels{'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'};
int half = s.size() / 2;
int vowelsFirstHalf = 0, vowelsSecondHalf = 0;
for (int i = 0; i < half; i++) {
if (vowels.count(s[i]))
vowelsFirstHalf++;
if (vowels.count(s[i + half]))
vowelsSecondHalf++;
}
return vowelsFirstHalf == vowelsSecondHalf;
}function halvesAreAlike(s) {
const vowels = new Set('aeiouAEIOU');
const half = s.length / 2;
let count1 = 0, count2 = 0;
for (let i = 0; i < half; i++) {
if (vowels.has(s[i])) count1++;
if (vowels.has(s[i + half])) count2++;
}
return count1 === count2;
}#include <stdbool.h>
#include <string.h>
bool isVowel(char ch) {
return ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u' ||
ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U';
}
bool halvesAreAlike(char * s) {
int length = strlen(s);
int half = length / 2;
int vowelsFirstHalf = 0, vowelsSecondHalf = 0;
for (int i = 0; i < half; i++) {
if (isVowel(s[i])) vowelsFirstHalf++;
if (isVowel(s[i + half])) vowelsSecondHalf++;
}
return vowelsFirstHalf == vowelsSecondHalf;
}using System;
using System.Collections.Generic;
public class Solution {
public bool HalvesAreAlike(string s) {
HashSet<char> vowels = new HashSet<char> { 'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U' };
int n = s.Length / 2;
int count1 = 0, count2 = 0;
for (int i = 0; i < n; i++) {
if (vowels.Contains(s[i])) count1++;
if (vowels.Contains(s[i + n])) count2++;
}
return count1 == count2;
}
}In this Python solution, a set is used to easily check if a character is a vowel. The string is split into two halves, and a generator expression counts the vowels in each half. If the counts are equal, the function returns true.
Time Complexity: O(n) due to a single pass through the string.
Space Complexity: O(1) for constant space of the vowel set.
Approach 2: Character Counting via Direct Comparison
This approach directly counts vowels in both halves of the string through string slicing.
Both halves of the string are iterated efficiently with a loop, accumulating vowel counts independently. The results are directly compared to ensure both halves are alike.
def halvesAreAlike(s: str) -> bool:
vowels = set('aeiouAEIOU')
half = len(s) // 2
vowels_count = [0, 0]
for i in range(half):
if s[i] in vowels:
vowels_count[0] += 1
if s[i + half] in vowels:
vowels_count[1] += 1
return vowels_count[0] == vowels_count[1]import java.util.Set;
public class Solution {
public boolean halvesAreAlike(String s) {
Set<Character> vowels = Set.of('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U');
int length = s.length(), half = length / 2;
int[] vowelCounts = new int[2];
for (int i = 0; i < half; i++) {
if (vowels.contains(s.charAt(i))) vowelCounts[0]++;
if (vowels.contains(s.charAt(i + half))) vowelCounts[1]++;
}
return vowelCounts[0] == vowelCounts[1];
}
}#include <string>
#include <unordered_set>
using namespace std;
bool halvesAreAlike(string s) {
unordered_set<char> vowels{'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'};
int length = s.size();
int half = length / 2;
int vowelCounts[2] = {0};
for (int i = 0; i < half; i++) {
if (vowels.count(s[i])) vowelCounts[0]++;
if (vowels.count(s[i + half])) vowelCounts[1]++;
}
return vowelCounts[0] == vowelCounts[1];
}function halvesAreAlike(s) {
const vowels = new Set('aeiouAEIOU');
const mid = s.length / 2;
const counts = [0, 0];
for (let i = 0; i < mid; i++) {
if (vowels.has(s[i])) counts[0]++;
if (vowels.has(s[i + mid])) counts[1]++;
}
return counts[0] === counts[1];
}#include <stdbool.h>
#include <string.h>
bool isVowel(char ch) {
return ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u' ||
ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U';
}
bool halvesAreAlike(char * s) {
int length = strlen(s);
int half = length / 2;
int vowelsCount[2] = {0};
for (int i = 0; i < half; i++) {
if (isVowel(s[i])) vowelsCount[0]++;
if (isVowel(s[i + half])) vowelsCount[1]++;
}
return vowelsCount[0] == vowelsCount[1];
}using System;
using System.Collections.Generic;
public class Solution {
public bool HalvesAreAlike(string s) {
HashSet<char> vowels = new HashSet<char> {'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'};
int n = s.Length / 2;
int[] vowelCounts = new int[2];
for (int i = 0; i < n; i++) {
if (vowels.Contains(s[i])) vowelCounts[0]++;
if (vowels.Contains(s[i + n])) vowelCounts[1]++;
}
return vowelCounts[0] == vowelCounts[1];
}
}Applying a detailed Pythonic idiomatic approach, lists compile intermediary forecasts. This technique harnesses brute-force slicing but Audits each slice-pass for variance, restoring space efficacy at minimal processing expense.
Time Complexity: O(n) enforced by constrained iteration.
Space Complexity: O(1) fostered through smaller data handling.
Approach 3: Counting
Traverse the string. If the number of vowels in the first half of the string is equal to the number of vowels in the second half, return true. Otherwise, return false.
The time complexity is O(n), where n is the length of the string. The space complexity is O(C), where C is the number of vowel characters.
function halvesAreAlike(s: string): boolean {
const vowels = new Set('aeiouAEIOU'.split(''));
let cnt = 0;
const n = s.length >> 1;
for (let i = 0; i < n; ++i) {
cnt += vowels.has(s[i]) ? 1 : 0;
cnt -= vowels.has(s[n + i]) ? 1 : 0;
}
return cnt === 0;
}func halvesAreAlike(s string) bool {
vowels := map[byte]bool{}
for _, c := range "aeiouAEIOU" {
vowels[byte(c)] = true
}
cnt, n := 0, len(s)>>1
for i := 0; i < n; i++ {
if vowels[s[i]] {
cnt++
}
if vowels[s[i+n]] {
cnt--
}
}
return cnt == 0
}impl Solution {
pub fn halves_are_alike(s: String) -> bool {
let n = s.len() / 2;
let vowels: std::collections::HashSet<char> = "aeiouAEIOU".chars().collect();
let mut cnt = 0;
for i in 0..n {
if vowels.contains(&s.chars().nth(i).unwrap()) {
cnt += 1;
}
if vowels.contains(&s.chars().nth(i + n).unwrap()) {
cnt -= 1;
}
}
cnt == 0
}
}class Solution {
/**
* @param String $s
* @return Boolean
*/
function halvesAreAlike($s) {
$n = strlen($s) / 2;
$vowels = ['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'];
$cnt = 0;
for ($i = 0; $i < $n; $i++) {
if (in_array($s[$i], $vowels)) {
$cnt++;
}
if (in_array($s[$i + $n], $vowels)) {
$cnt--;
}
}
return $cnt == 0;
}
}Complexity comparison
| Approach | Complexity |
|---|---|
| Two-Pointer Vowel Count Approach | Time Complexity: O(n) due to a single pass through the string. Space Complexity: O(1) for constant space of the vowel set. |
| Character Counting via Direct Comparison | Time Complexity: O(n) enforced by constrained iteration. Space Complexity: O(1) fostered through smaller data handling. |
| Counting | – |
Complexity analysis
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Character Counting via Direct Comparison | O(n) | O(1) | When clarity and straightforward logic are preferred; good baseline solution |
| Two-Pointer Vowel Count Approach | O(n) | O(1) | When comparing two segments simultaneously with cleaner single-pass traversal |
Frequently asked questions
Is Determine if String Halves Are Alike easy or hard?
Determine if String Halves Are Alike is classified as an Easy problem. The challenge focuses on correct string traversal and vowel counting rather than advanced algorithms or data structures.
Determine if String Halves Are Alike Python/Java solution
In Python or Java, iterate through both halves of the string and check if each character belongs to a vowel set such as "aeiouAEIOU". Maintain two counters (or a difference counter) and compare the totals after traversal. The implementation runs in O(n) time and O(1) space.
How to solve Determine if String Halves Are Alike in O(n)?
Split the string logically using its midpoint. Count vowels in the first half and the second half while iterating through the string. Using two pointers or a single loop with conditional counting ensures every character is processed once, producing an O(n) time and O(1) space solution.
What is the best approach for Determine if String Halves Are Alike?
The two-pointer vowel count approach is typically the best solution. One pointer scans the first half while another scans the second half, updating counters or a difference value when vowels appear. This processes the string in a single pass with O(n) time complexity and O(1) extra space.
Is Determine if String Halves Are Alike asked at Google/Amazon/Meta?
Problems involving string traversal and counting patterns are common in interviews at companies like Amazon, Google, and Meta. While this exact question is categorized as easy, it tests clean string handling and iteration logic frequently expected in coding interviews.
What data structure is used in Determine if String Halves Are Alike?
The solution primarily uses basic string traversal and simple counters. Many implementations store vowels in a small hash set or string for constant-time membership checks, but no complex data structures are required.
What is the time complexity of Determine if String Halves Are Alike?
The optimal time complexity is O(n), where n is the length of the string. Each character is checked at most once to determine whether it is a vowel. The algorithm only uses a few counters and constant-size vowel checks, resulting in O(1) auxiliary space.
