Problem overview
The function is_palindrome takes a String called input and returns a bool: true if the text reads the same forwards and backwards, false otherwise. Spaces count as characters, so "madam racecar madam" is a palindrome (reversed, it is the same text), and "abcbx" is not.
Approach: build the reverse and compare
The definition of a palindrome translates directly into code: reverse the string and see whether the result equals the original. If every character matches its mirror position, the reversed text is identical to the input. If any pair differs, the two strings differ.
This is the most direct solution, and it is easy to get right. A two-pointer scan, comparing the first and last characters and moving inward, also works and avoids building a second string. That version is a different lesson. Here the focus is on Rust's iterator tools and on the idea that a comparison is already an answer.
Step by step
- Build the reversed string.
input.chars()walks the characters,rev()reverses the walk, andcollect()gathers the characters into a newStringcalledrev. The annotation: Stringon the variable is what tellscollect()which kind of collection to build. - Return the comparison.
input == revistruewhen the two strings hold the same characters in the same order, andfalseotherwise. Leave it as the last expression of the function, without areturnkeyword or a semicolon. Noifis needed, because the comparison already is theboolto return.
Tracing "abcbx": the reverse is "xbcba". The first characters differ, a against x, so the strings are not equal and the function returns false. For "abba" the reverse is "abba" and the answer is true.
The solution in Rust
impl Solution {
fn is_palindrome(input: String) -> bool {
let rev: String = input.chars().rev().collect();
input == rev
}
}
Rust details worth knowing:
collect()is generic. The same method can build aVec, aString, aHashMapand more. Rust picks one from the type you ask for. Without the: Stringannotation, the compiler can't tell and reports an error asking for a type.==compares contents. ForStringvalues,==checks the characters, not where the strings live in memory. You don't need a specialequalsmethod.- The comparison borrows. Using
==doesn't moveinputorrev. Both are only read. - Whole characters.
chars()yields complete Unicode characters, so"été"is correctly seen as a palindrome. Reversing the bytes instead would splitéinto two pieces. - The tail expression. A line without a semicolon at the end of the function is its result. Writing
input == rev;would make the function return()and the compiler would complain about the type.
Complexity
Time: O(n). Reversing walks the string once, and the comparison walks it once more. Both are linear in the length n.
Space: O(n). The reversed copy is as long as the input. The statement asks for O(1) extra space, which the two-pointer scan achieves, but this version stores a second string, so it does not meet that bound.
Edge cases and common mistakes
- Empty string. The reverse of
""is"", so the function returnstrue. - One character.
"a"is its own reverse, so the answer istrue. - Case matters.
"Madam"reverses to"madaM", so the function returnsfalse. Making it case-insensitive would require converting the text to lower case first. - Spaces matter.
"a b a"is a palindrome, but"ab a"is not, because its reverse is"a ba". - Missing annotation.
let rev = input.chars().rev().collect();doesn't compile, because nothing says what to collect into. - Comparing the wrong things. Comparing
inputwith itself, or forgettingrev(), makes the answer alwaystrue.
Testing
"madam racecar madam"givestrue."abcbx"givesfalse."abba"givestrue.""givestrue."Madam"givesfalse.
