Start learning free

LESSON 243 OF 671 · HELPER FUNCTIONS

Palindrome Words in JavaScript with a Helper Method

Practice Read the full explanation

You get an array of words, words. Return the words that are palindromes, in the same order.

A palindrome reads the same from left to right and from right to left, like "noon". A word with one letter is a palindrome too. If no word is a palindrome, the result is empty.

The work is split between two functions. The first one is a helper. It gets one word and returns true if it is a palindrome, false if not. The second one is the function that is graded. It keeps the words for which the helper returns true.

The helper compares the letters from both ends of the word, in one loop. Don't use a built-in function that reverses the word.

 

Example 1:

Input: words = ["pup", "cat", "noon", "dog"]
Output: ["pup", "noon"]
Explanation: The words "pup" and "noon" read the same both ways.
Read backwards, "cat" is "tac".
Read backwards, "dog" is "god".

Example 2:

Input: words = ["a", "bob", "abba", "ab"]
Output: ["a", "bob", "abba"]
Explanation: The word "a" has one letter, so it is a palindrome.
Read backwards, "ab" is "ba".

Example 3:

Input: words = ["kitten", "parrot"]
Output: []
Explanation: No word reads the same both ways.

 

Constraints:

  • words has at least one word.
  • Every word has 1 to 20 lowercase letters.
  • A word can appear more than once. Each palindrome is kept every time it appears.
STEP 1 OF 8
    Ctrl + Enter to check

    JAVASCRIPT · HELPER FUNCTIONS

    Palindrome Words in JavaScript, explained

    Problem overview

    The method palindromeWords gets an array of lowercase words and returns the ones that are palindromes, in the same order. A palindrome reads the same from left to right and from right to left, like "noon". A word with one letter is a palindrome too. A word that appears more than once is kept every time it appears, and if no word is a palindrome the result is an empty array.

    For ["pup", "cat", "noon", "dog"] the answer is ["pup", "noon"]. For ["a", "bob", "abba", "ab"] the answer is ["a", "bob", "abba"]. For ["kitten", "parrot"] the answer is empty.

    Approach: a helper for one word

    The work is split in two. The helper isPalindrome answers one question about one word: true or false. palindromeWords loops over the array and keeps the words for which the helper says true.

    The helper compares letters in pairs from both ends: the first with the last, the second with the second to last, and so on. If any pair differs, the word is not a palindrome. If no pair differs, it is. Only half of the word needs checking, because the second half repeats the same pairs. The lesson asks for this one-loop comparison, so the word is never reversed.

    Step by step

    1. In isPalindrome, store the length of the word in n with let n = word.length. The loop and the partner index both need it.
    2. Loop over the first half: for (let i = 0; i < n / 2; i++). Each turn compares one letter from the front with one from the back.
    3. Compare with the partner. The partner of word[i] is word[n - 1 - i]: for i = 0 it is the last letter, for i = 1 the one before it. If the two differ, return false right away.
    4. Return true after the loop. No pair was different. A one-letter word runs the loop once, for i = 0, where the letter is compared with itself, and gets here too.
    5. In palindromeWords, start with an empty array named palindromes.
    6. Loop over the words with for (let word of words), first to last, so the order is kept.
    7. Call the helper inside an if: this.isPalindrome(word) is already true or false, so it goes straight into the condition. Push word when it is true.
    8. Return palindromes after the loop.

    The solution in JavaScript

    class Solution {
        isPalindrome(word) {
            let n = word.length;
            for (let i = 0; i < n / 2; i++) {
                if (word[i] != word[n - 1 - i]) {
                    return false;
                }
            }
            return true;
        }
        palindromeWords(words) {
            let palindromes = [];
            for (let word of words) {
                if (this.isPalindrome(word)) {
                    palindromes.push(word);
                }
            }
            return palindromes;
        }
    }
    

    Some details worth a look:

    • Dividing by 2 gives a fraction. In JavaScript, 5 / 2 is 2.5, not 2. The loop condition i < n / 2 still works: for 5 letters, i takes the values 0, 1 and 2, and 2 is the middle letter, which is compared with itself. That is harmless. For 4 letters, i is 0 and 1.
    • Indexing a string. word[i] gives a one-character string, and != compares two such strings by content.
    • Calling the helper. Inside the class, use this.isPalindrome(word).

    Following two words

    For "noon", n is 4 and the loop runs for i = 0 and i = 1. At i = 0 the helper compares word[0], "n", with word[3], "n": equal. At i = 1 it compares word[1], "o", with word[2], "o": equal. The loop ends and the helper returns true.

    For "cat", n is 3. At i = 0 it compares "c" with word[2], "t". They differ, so the helper returns false at once, without looking at the rest. Stopping at the first mismatch is why the helper has two different return statements: one inside the loop for a mismatch, one after it for a word whose pairs all matched.

    Testing

    The helper on single words returns true for "noon", false for "cat", true for "a" and true for "level". On the statement's examples, the lesson's solution prints these lines, with an empty line for the last example:

    pup noon
    a bob abba
    

    A word with five letters, such as "level", is checked with i equal to 0, 1 and 2, because the loop runs while i < 2.5; the helper returns true for it. The word "abca" fails on the second pair, where b meets c.

    Common mistakes

    • Returning true inside the loop. A match between one pair says nothing about the other pairs. If the loop returns true on the first matching pair, "abca" gives true, and so do "cat" and "dog", because their middle letter matches itself. Return false on a mismatch, and true only after the loop.
    • Looping to n instead of half. It still gives the right answer, because the second half repeats the same pairs, but it does twice the work.
    • Forgetting the - 1. The last letter is at index n - 1. word[n - i] starts at word[n], which is undefined, so the first comparison fails and every word, even "a", looks like it is not a palindrome.
    • Dropping duplicates. A palindrome that appears twice is kept twice. The loop visits it twice, so it is pushed twice.
    Keep going with JavaScript500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free