Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to find longest nice substring using Python
A nice substring is one where every letter appears in both uppercase and lowercase. For example, "bBb" is nice because 'b' appears as both 'b' and 'B'. This tutorial shows how to find the longest nice substring in Python.
Problem Understanding
Given a string, we need to find the longest substring where every letter appears in both uppercase and lowercase forms. If multiple substrings have the same maximum length, return the one that appears first.
Algorithm Approach
We'll use a nested loop approach to check all possible substrings:
For each starting position, build a substring character by character
Track uppercase and lowercase letters using sets
Check if all letters appear in both forms
Keep track of the longest valid substring found
Implementation
def find_longest_nice_substring(s):
cur_max = -1
res = ""
for i in range(len(s)):
upper = set()
lower = set()
# Process first character
c = s[i]
if c.islower():
lower.add(c)
if c.isupper():
upper.add(c.lower())
# Extend substring from position i
for j in range(i + 1, len(s)):
c = s[j]
if c.islower():
lower.add(c)
if c.isupper():
upper.add(c.lower())
# Check if current substring is nice
if upper == lower and len(upper) > 0:
if j - i > cur_max:
cur_max = j - i
res = s[i:j+1]
return res
# Test the function
s = "ZbybBbz"
result = find_longest_nice_substring(s)
print(f"Input: {s}")
print(f"Longest nice substring: '{result}'")
Input: ZbybBbz Longest nice substring: 'bBb'
How It Works
Let's trace through the example "ZbybBbz":
Starting at index 0 ('Z'): Only uppercase 'Z', no lowercase 'z' in subsequent characters
Starting at index 1 ('b'): When we reach index 3 ('B'), we have both 'b' and 'B' ? nice substring "byb" isn't valid because 'y' appears only in lowercase
Starting at index 2 ('y'): When we reach "bB", we get a nice substring "bBb" of length 3
Alternative Approaches
Here's a more optimized version using divide and conquer:
def find_longest_nice_optimized(s):
if len(s) < 2:
return ""
# Find all unique characters
chars = set(s)
# Find characters that don't have both cases
for i, c in enumerate(s):
if c.swapcase() not in chars:
# Split at this character and recurse
left = find_longest_nice_optimized(s[:i])
right = find_longest_nice_optimized(s[i+1:])
return left if len(left) >= len(right) else right
# All characters have both cases
return s
# Test both approaches
s = "ZbybBbz"
print(f"Brute force: '{find_longest_nice_substring(s)}'")
print(f"Optimized: '{find_longest_nice_optimized(s)}'")
Brute force: 'bBb' Optimized: 'bBb'
Comparison
| Approach | Time Complexity | Space Complexity | Best For |
|---|---|---|---|
| Brute Force | O(n³) | O(1) | Simple understanding |
| Divide & Conquer | O(n²) | O(n) | Better performance |
Conclusion
The brute force approach checks all substrings systematically, while the divide and conquer method optimizes by splitting at invalid characters. Both methods effectively find the longest nice substring where every letter appears in both uppercase and lowercase forms.
