{x}
blog image

To Lower Case

Given a string s, return the string after replacing every uppercase letter with the same lowercase letter.

 

Example 1:

Input: s = "Hello"
Output: "hello"

Example 2:

Input: s = "here"
Output: "here"

Example 3:

Input: s = "LOVELY"
Output: "lovely"

 

Constraints:

  • 1 <= s.length <= 100
  • s consists of printable ASCII characters.

Solution Explanation for 709. To Lower Case

This problem requires converting a given string s to lowercase. The most efficient way to do this involves leveraging built-in string manipulation functions or bitwise operations. Let's examine the approaches and analyze their time and space complexity.

Approach 1: Bitwise Operation (Most Efficient)

This approach directly modifies the ASCII value of uppercase characters to convert them to lowercase. The ASCII value difference between an uppercase letter and its lowercase counterpart is 32. We can use a bitwise OR operation (|= 32) to achieve this efficiently.

Time Complexity: O(n), where n is the length of the string. We iterate through the string once.

Space Complexity: O(1) (In-place modification for languages that support it, otherwise O(n) for creating a new string). In languages like C++, we modify the string in place, using constant extra space. In languages like Python, we create a new string, resulting in O(n) space complexity.

Code Examples:

  • Python:
class Solution:
    def toLowerCase(self, s: str) -> str:
        return "".join([chr(ord(c) | 32) if c.isupper() else c for c in s])
  • Java:
class Solution {
    public String toLowerCase(String s) {
        char[] cs = s.toCharArray();
        for (int i = 0; i < cs.length; ++i) {
            if (cs[i] >= 'A' && cs[i] <= 'Z') {
                cs[i] |= 32;
            }
        }
        return String.valueOf(cs);
    }
}
  • C++:
class Solution {
public:
    string toLowerCase(string s) {
        for (char& c : s) {
            if (c >= 'A' && c <= 'Z') {
                c |= 32;
            }
        }
        return s;
    }
};
  • Go:
func toLowerCase(s string) string {
	cs := []byte(s)
	for i, c := range cs {
		if c >= 'A' && c <= 'Z' {
			cs[i] |= 32
		}
	}
	return string(cs)
}

The C and C++ solutions modify the string in place, enhancing efficiency. The Python and Java solutions create new string objects.

Approach 2: Using Built-in Functions (Less Efficient but More Readable)

Many programming languages provide built-in functions for converting strings to lowercase. This approach is generally less efficient than the bitwise operation, especially for very large strings, but it's more concise and readable.

Time Complexity: The time complexity of built-in toLowerCase() functions varies depending on the language implementation, but it's typically O(n).

Space Complexity: O(n) in most cases, as a new string is usually created.

Code Examples:

  • TypeScript:
function toLowerCase(s: string): string {
    return s.toLowerCase();
}
  • Rust:
impl Solution {
    pub fn to_lower_case(s: String) -> String {
        s.to_ascii_lowercase()
    }
}

This approach sacrifices a bit of performance for improved readability. The choice between the two approaches depends on the prioritization of performance vs. code clarity. For most scenarios, especially those involving relatively short strings, the readability advantage of the built-in function approach may outweigh the minor performance difference.