力扣每日一刷--- 验证回文字符串II(非严格) 以及取反知识

题目:给定一个非空字符串 s,最多删除一个字符。判断是否能成为回文字符串。
注意:字符串只包含从 a-z 的小写字母。字符串的最大长度是50000。
我的代码

class Solution:
    def validPalindrome(self, s: str) -> bool:
        # 分三种情况:不删字符是回文字符串,删一个字符是回文字符串,不是回文字符串
        if s == s[::-1]:
            return True
        # 双指针
        low = 0
        high = len(s) - 1
        while low < high:
            if s[low] != s[high]:
            # 只需要判断删除后的字符是否是回文字符串
                # 删除右边字符
                temp1 = s[low:high]
                # 删除左边字符
                temp2 = s[low+1:high+1]
                if temp1 == temp1[::-1]:
                    return True
                elif temp2 == temp2[::-1]:
                    return True
                else:
                    return False
            else:
                low += 1
                high -= 1

时间复杂度:O(N)
空间复杂度:O(N)
别人的代码

利用 ~i 将i的二进制补码按位取反
关于二进制补码的介绍
正数:正数的原码、反码、补码都一样(后面以8位bit下的值为例)首位符号位代表正负
2的原码:0000 0010 首位符号位0表示正数
2的反码:0000 0010
2的补码:0000 0010
~2表示对2的补码按位取反:1111 1101

负数:负数的反码、补码需要计算
-3的原码:1000 0011 首位符号位-1表示负数
-3的反码:1111 1100 首位符号位不变,其余各位取反
-3的补码:1111 1101 反码+1
~(-3)表示对-3的补码取反:0000 0010

所以
~2 =1111 1101 = -3
~(-3) = 0000 0010 = 2
综上所述:~i = -(i+1)
总结
1.正数的正码、反码、补码是一致的
2.负数的反码-首位符号位变不变,其余各位取反;负数的补码:反码+1
3.计算机的数字运算是基于补码的

class Solution:
    def validPalindrome(self, s: str) -> bool:
        # 正常回文字符串
        n = len(s)
        w = n // 2
        if s == s[::-1]:
            return True
        # 利用~判断非正常字符串  ~i = -(i+1)
        for i in range(w):
            if s[i] != s[~i]:
                j = len(s) - 1 - i 
                h = (j-i)//2
                # 分别删除第一个或最后一个字符串
                return s[i:i+h] == s[j-1:j-h-1:-1] or s[i+1:i+h+1] == s[j:j-h:-1]

你可能感兴趣的:(leetcode)