Decrease the complexity of isPalindrome solution?

耗尽温柔 提交于 2019-12-11 11:56:57

问题


Here is my isPalindrome method

public static boolean isPalindrome(String s){
    for(int i = 0; i < s.length()/2; i++){
        int j = s.length() - 1 - i;
        if(s.charAt(i) != s.charAt(j))
            return false;
    }
    return true;
}

my teacher says I can decrease the complexity, but I can't see how. I already am only going through half of the string. Is there any way to decrease the complexity of this solution?


回答1:


You could try something like this:

public static boolean isPalindrome (String str) {
    int left = 0;
    int right = str.length() - 1;

    while (left < right) {
        if (str.charAt(left) != str.charAt(right))
            return false;
        left++;
        right--;
    }
    return true;
}

This has the advantage of not calculating the right hand index each time through the loop, especially since it has to access the string length each time (which is constant).

As an aside, I also tend to prefer more meaningful variable names than s, i and j - my basic rule is that, if you have to resort to j at all, you're better off naming your counters more expressively (i is okay if it's the only counter).




回答2:


The only thing I can think to do would be to store the length of s:

final int n = s.length();
for(int i=0; i<n/2; i++) {
    int j = n-1-i;
    if(s.charAt(i) != s.charAt(j))
        return false;
}
return true;

Aside from that, I don't see how you can make it any simpler or more efficient.




回答3:


If he means the complexity of how your code appears aesthetically, then here's a recursive solution:

public static boolean isPalindrome(String s) {
    if (s.charAt(0) != s.charAt(s.length() - 1)
       return false;
    return isPalindrome(s.substring(1, s.length() - 1);
}

If he means the complexity of the algorithm, I am not sure if you could do it any faster. Perhaps you could move substrings onto different cores (using threading) and then combine the results.

EDIT: paxdiablo suggested better code and I re-pended* it in.




回答4:


If you reverse the string and it still equals itself, that means it's a palindrome. Here's how I'd implement it:

package com.sandbox;

import org.apache.commons.lang.StringUtils;
import org.junit.Test;

import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;

public class PalindromeTest {

    @Test
    public void testTheseArePalindromes() {
        assertTrue(isPalindrome("abccba"));
        assertTrue(isPalindrome("121"));
        assertTrue(isPalindrome("Malayalam"));
        assertTrue(isPalindrome("peeweep"));
        assertTrue(isPalindrome("123 321"));
    }

    @Test
    public void testTheseAreNOTPalindromes() {
        assertFalse(isPalindrome("abc"));
        assertFalse(isPalindrome("123"));
        assertFalse(isPalindrome("123 123"));
    }

    private boolean isPalindrome(String input) {
        String lowerIn = input.toLowerCase();
        String reversed = StringUtils.reverse(lowerIn);
        return lowerIn.equals(reversed);
    }

}

The phrases on this page are also palindromes. Does it have to work on those? If it does, it's a very simple change:

package com.sandbox;

import org.apache.commons.lang.StringUtils;
import org.junit.Test;

import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;

public class PalindromeTest {

    @Test
    public void testTheseArePalindromes() {
        assertTrue(isPalindrome("abccba"));
        assertTrue(isPalindrome("121"));
        assertTrue(isPalindrome("Malayalam"));
        assertTrue(isPalindrome("peeweep"));
        assertTrue(isPalindrome("123 321"));
        assertTrue(isPalindrome("A dog, a plan, a canal: pagoda."));
        assertTrue(isPalindrome("A man, a plan, a canal: Panama."));
        assertTrue(isPalindrome("A tin mug for a jar of gum, Nita."));
    }

    @Test
    public void testTheseAreNOTPalindromes() {
        assertFalse(isPalindrome("abc"));
        assertFalse(isPalindrome("123"));
        assertFalse(isPalindrome("123 123"));
    }

    private boolean isPalindrome(String input) {
        String removedPunctuation = input.toLowerCase().replaceAll("[.,;: \t]", "");
        String reversed = StringUtils.reverse(removedPunctuation);
        return removedPunctuation.equals(reversed);
    }

}



回答5:


Here is my solution for C#, I have not speed tested it.

using System;

public class Palindrome
{
    public static bool IsPalindrome(string word)
    {
        var arr = word.ToCharArray();
        Array.Reverse(arr);
        return word.ToLower() == new string(arr).ToLower() ? true : false;
    }

    public static void Main(string[] args)
    {
        Console.WriteLine(Palindrome.IsPalindrome("Deleveled"));
    }
}


来源:https://stackoverflow.com/questions/14573631/decrease-the-complexity-of-ispalindrome-solution

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!