当前位置: 首页 > news >正文

剑指 Offer II 019. 最多删除一个字符得到回文


comments: true
edit_url: https://github.com/doocs/leetcode/edit/main/lcof2/%E5%89%91%E6%8C%87%20Offer%20II%20019.%20%E6%9C%80%E5%A4%9A%E5%88%A0%E9%99%A4%E4%B8%80%E4%B8%AA%E5%AD%97%E7%AC%A6%E5%BE%97%E5%88%B0%E5%9B%9E%E6%96%87/README.md

剑指 Offer II 019. 最多删除一个字符得到回文

题目描述

给定一个非空字符串 s,请判断如果 最多 从字符串中删除一个字符能否得到一个回文字符串。

 

示例 1:

输入: s = "aba"
输出: true

示例 2:

输入: s = "abca"
输出: true
解释: 可以删除 "c" 字符 或者 "b" 字符

示例 3:

输入: s = "abc"
输出: false

 

提示:

  • 1 <= s.length <= 105
  • s 由小写英文字母组成

 

注意:本题与主站 680 题相同: https://leetcode.cn/problems/valid-palindrome-ii/

解法

方法一:双指针

我们用两个指针 i i i j j j 分别指向字符串 s s s 的第一个字符和最后一个字符,然后向中间移动指针,每次判断 s [ i ] s[i] s[i] s [ j ] s[j] s[j] 是否相等:

  • 如果 s [ i ] = s [ j ] s[i] = s[j] s[i]=s[j],则指针 i i i 向后移动一位,指针 j j j 向前移动一位;
  • 否则,存在两种情况,即删除字符 s [ i ] s[i] s[i] 或者删除字符 s [ j ] s[j] s[j],然后判断删除之后的字符串是否是回文字符串。即判断子串 s [ i + 1.. j ] s[i+1..j] s[i+1..j] 或者子串 s [ i . . j − 1 ] s[i..j-1] s[i..j1] 是否是回文字符串。【若存在回文,s[i],s[j]中必有一个阻塞】

时间复杂度 O ( n ) O(n) O(n),其中 n n n 是字符串 s s s 的长度。空间复杂度 O ( 1 ) O(1) O(1)

Python3
class Solution:
    def validPalindrome(self, s: str) -> bool:
        def check(i,j):
            while i<j:
                if s[i]!=s[j]:return False
                i,j=i+1,j-1
            return True
        
        l,r=0,len(s)-1
        while l<r:
            if s[l]!=s[r]: #若存在回文,s[i],s[j]中必有一个阻塞
                return check(l,r-1) or check(l+1,r)
            l,r=l+1,r-1
        return True #本身就是回文,while中就不会经过if         
Java
class Solution {
    private String s;

    public boolean validPalindrome(String s) {
        this.s = s;
        for (int i = 0, j = s.length() - 1; i < j; ++i, --j) {
            if (s.charAt(i) != s.charAt(j)) {
                return check(i + 1, j) || check(i, j - 1);
            }
        }
        return true;
    }

    private boolean check(int i, int j) {
        for (; i < j; ++i, --j) {
            if (s.charAt(i) != s.charAt(j)) {
                return false;
            }
        }
        return true;
    }
}
C++
class Solution {
public:
    bool validPalindrome(string s) {
        auto check = [&](int i, int j) {
            for (; i < j; ++i, --j) {
                if (s[i] != s[j]) {
                    return false;
                }
            }
            return true;
        };
        for (int i = 0, j = s.size() - 1; i < j; ++i, --j) {
            if (s[i] != s[j]) {
                return check(i + 1, j) || check(i, j - 1);
            }
        }
        return true;
    }
};
Go
func validPalindrome(s string) bool {
	check := func(i, j int) bool {
		for ; i < j; i, j = i+1, j-1 {
			if s[i] != s[j] {
				return false
			}
		}
		return true
	}
	for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
		if s[i] != s[j] {
			return check(i+1, j) || check(i, j-1)
		}
	}
	return true
}
TypeScript
function validPalindrome(s: string): boolean {
    const check = (i: number, j: number): boolean => {
        for (; i < j; ++i, --j) {
            if (s[i] !== s[j]) {
                return false;
            }
        }
        return true;
    };
    for (let i = 0, j = s.length - 1; i < j; ++i, --j) {
        if (s[i] !== s[j]) {
            return check(i + 1, j) || check(i, j - 1);
        }
    }
    return true;
}
JavaScript
/**
 * @param {string} s
 * @return {boolean}
 */
var validPalindrome = function (s) {
    const check = (i, j) => {
        for (; i < j; ++i, --j) {
            if (s[i] !== s[j]) {
                return false;
            }
        }
        return true;
    };
    for (let i = 0, j = s.length - 1; i < j; ++i, --j) {
        if (s[i] !== s[j]) {
            return check(i + 1, j) || check(i, j - 1);
        }
    }
    return true;
};
Swift
class Solution {
    private var s: String = ""

    func validPalindrome(_ s: String) -> Bool {
        self.s = s
        var i = s.startIndex
        var j = s.index(before: s.endIndex)

        while i < j {
            if s[i] != s[j] {
                return check(s.index(after: i), j) || check(i, s.index(before: j))
            }
            i = s.index(after: i)
            j = s.index(before: j)
        }
        return true
    }

    private func check(_ i: String.Index, _ j: String.Index) -> Bool {
        var i = i
        var j = j
        while i < j {
            if s[i] != s[j] {
                return false
            }
            i = s.index(after: i)
            j = s.index(before: j)
        }
        return true
    }
}

相关文章:

  • Macos机器hosts文件便捷修改工具——SwitchHosts
  • Jmeter断言、关联、录制脚本
  • 【ISO 14229-1:2023 UDS诊断全量测试用例清单系列:第十六节】
  • Seaweedfs(master volume filer) docker run参数帮助文档
  • STM32 外部中断和NVIC嵌套中断向量控制器
  • 内容中台重构企业内容管理流程驱动智能协作升级
  • 【一文读懂】什么是MVVM?
  • 打印问题总结
  • Redis之持久化
  • Vue 实现主题切换(明暗)
  • 解密DNSlog
  • FTP服务
  • 「软件设计模式」单例模式(Singleton)
  • Python的那些事第二十三篇:Express(Node.js)与 Python:一场跨语言的浪漫邂逅
  • MySQL DELETE 语句
  • 数据结构6-二叉树、时间复杂度
  • C# 使用FreeSpire.doc 生成带有页码的目录
  • 力扣 438.找到字符串中所有字母异位词
  • osgearth视点坐标及鼠标交点坐标的信息显示(七)
  • 仿叮咚买菜鸿蒙原生APP
  • 中使馆:奉劝菲方有关人士不要在台湾问题上挑衅,玩火者必自焚
  • “五一”假期,又有多地将向社会开放政府机关食堂
  • 圆桌|特朗普上台百日未能结束俄乌冲突,若美国“退出”会发生什么?
  • 新质观察|重塑低空经济的系统安全观
  • 传智教育连续3个交易日跌停:去年净利润由盈转亏
  • 第二十届中国电影华表奖揭晓!完整获奖名单来了