剑指offer 专项突破版 19、最多删除一个字符得到回文

题目链接

思路一

正常双指针遍历,用一个boolean数组保存左侧和右侧是否删除过,与此同时还需要两个int变量记录删除前的left和right指针的位置

class Solution {

    private final int LEFT = 0, RIGHT = 1;

    public boolean validPalindrome(String s) {

        //flags数组用于记录左右两边是否被删除过
        boolean[] flags = new boolean[2];
        int left = 0, right = s.length() - 1, preLeft = 0, preRight = 0;

        while (left < right) {
            if (s.charAt(left) != s.charAt(right)) {
                //如果左侧未删除过 那就删除左侧(left++),并记录删除前的位置
                if (!flags[LEFT]) {
                    flags[LEFT] = true;
                    preLeft = left++;
                    preRight = right;
                }//如果左侧删除过,那就判断右侧是否删除过,如果没有那就恢复到左侧删除前,并删除右侧的
                else if (!flags[RIGHT]) {
                    flags[RIGHT] = true;
                    left = preLeft;
                    right = preRight - 1;
                } else
                    break;
            } else {
                left++;
                right--;
            }
        }
        return left >= right;
    }
}

思路二

可以不用记录删除前的位置,我们知道有三种情况应该返回true

  • 本来就是回文
  • 删除左侧某一个字符后是回文
  • 删除右侧某一个字符后是回文
    所以说在第一次判断不是回文后直接再判断两次即可,三种情况取或
class Solution {

    boolean isPalindrome(String s, int begin, int end) {

        for (; begin < end; begin++, end--) {
            if (s.charAt(begin) != s.charAt(end))
                break;
        }
        return begin >= end;
    }

    public boolean validPalindrome(String s) {

        int left = 0, right = s.length() - 1;

        for (; left < right; left++, right--) {
            if (s.charAt(left) != s.charAt(right))
                break;
        }
        return left >= right || isPalindrome(s, left + 1, right) || isPalindrome(s, left, right - 1);
    }
}

注意

  • 双指针问题left向前,right向后时,注意是right–
  • 函数在设计时最好只有一个出口

Go版本

func validPalindrome(s string) bool {
	left, right := 0, len(s)-1
	for left < right {
		if s[left] != s[right] {
			return isPal(s, left, right-1) || isPal(s, left+1, right)
		}
		left++
		right--
	}
	return true
}

func isPal(s string, left, right int) bool {
	for left < right {
		if s[left] != s[right] {
			return false
		}
		left++
		right--
	}
	return true
}

你可能感兴趣的:(算法,leetcode,算法,职场和发展)