leetcode刷题

好好刷题

反转整数(easy)

$ 2^ {31} -1=2147483647 $

$ -2^{31} =-2147483648 $

数学方法

一般做法:取模运算

但是忽略了负数以及题目范围

上图中,绿色的是最大32位整数
第二排数字中,橘子的是5,它是大于上面同位置的4,这就意味着5后跟任何数字,都会比最大32为整数都大。
所以,我们到【最大数的1/10】时,就要开始判断了
如果某个数字大于 214748364那后面就不用再判断了,肯定溢出了。
如果某个数字等于 214748364呢,这对应到上图中第三、第四、第五排的数字,需要要跟最大数的末尾数字比较,如果这个数字比7还大,说明溢出了。

负数同理

class Solution {
    public int reverse(int x) {
        int res = 0;
        while(x!=0) {
            //每次取末尾数字
            int tmp = x%10;
            //判断是否 大于 最大32位整数
            if (res>214748364 || (res==214748364 && tmp>7)) {
                return 0;
            }
            //判断是否 小于 最小32位整数
            if (res<-214748364 || (res==-214748364 && tmp<-8)) {
                return 0;
            }
            res = res*10 + tmp;
            x /= 10;
        }
        return res;
    }
}			

关键点:
1.判断整数的正负
2.判断反转后的整数是否溢出

切片反转

python的话可以直接转成字符串切片

class Solution:
    def reverse(self, x: int) -> int:
        #将整数的绝对值转换成字符串
        s=str(abs(x))
        #翻转字符串
        s=s[::-1]
        #如果输入整数是负数,增加负号
        if x <0:
            s ='-' + s
        #转换为整数
        result = int(s)
        #判断是否溢出
        if result>=-2**31 and result<=2**31-1:
            return result
        else:
            return 0

还有大佬写的很丝滑

class Solution:
    def reverse(self, x: int) -> int:
        s = str(x)
        if s[0] == '-':
            x = int('-' + s[1:][::-1])
        else:
            x = int(s[::-1])
        return x if -2147483648< x <2147483647 else 0

我们可以一次构建反转整数的一位数字。在这样做的时候,我们可以预先检查向原整数附加另一位数字是否会导致溢出。
反转整数的方法可以与反转字符串进行类比。

我们想重复 “弹出” x 的最后一位数字,并将它 “推入” 到 res 的后面。最后,res 将与 x 相反。

取模

def reverse_better(self, x: int) -> int:
        y, res = abs(x), 0
        # 则其数值范围为 [−2^31,  2^31 − 1]
        boundry = (1<<31) -1 if x>0 else 1<<31
        while y != 0:
            res = res*10 +y%10
            if res > boundry :
                return 0
            y //=10
        return res if x >0 else -res

这里用移位来表示的边界$ 1<<31=2^{31} $
先将x进行abs,取绝对值,所以当x小于零的话边界就是1<<31,如果大于零就是(1<<31) -1,数字y>boundry就表示数字在范围外,这里的数字y其实就是x的取绝对值的数,所以可以这样表示,return的时候再把负号加上去

复习一下 python 的位运算符:

(a & b)
按位与运算符:参与运算的两个值,如果两个相应位都为 1,则该位的结果为 1,否则为 0 。
输出结果 12 ,二进制解释: 0000 1100

(a | b)
按位或运算符:只要对应的二个二进位有一个为1时,结果位就为1。
输出结果 61 ,二进制解释: 0011 1101

(a ^ b)
按位异或运算符:当两对应的二进位相异时,结果为 1
输出结果 49 ,二进制解释: 0011 0001

(~a )
按位取反运算符:对数据的每个二进制位取反,即把 1 变为 0,把 0 变为 1 。~x 类似于 -x-1
输出结果 -61 ,二进制解释: 1100 0011,在一个有符号二进制数的补码形式。

a << 2
左移动运算符:运算数的各二进位全部左移若干位,由 << 右边的数字指定了移动的位数,高位丢弃,低位补 0。
输出结果 240 ,二进制解释: 1111 0000

a >> 2
右移动运算符:把 ">>" 左边的运算数的各二进位全部右移若干位,>> 右边的数字指定了移动的位数
输出结果 15 ,二进制解释: 0000 1111

python 赋值运算符:

*= 乘法赋值运算符 c *= a 等效于 c = c * a
/= 除法赋值运算符 c /= a 等效于 c = c / a
%= 取模赋值运算符c %= a等效于 c = c % a
**= 幂赋值运算符 c **= a 等效于 c = c ** a
//= 取整除赋值运算符 c //= a 等效于 c = c // a

栈思路

class Solution:
    def reverse(self, x: int) -> int:
        stack = []              # 创建一个中间栈
        x = str(x)
        for i in x:
            if i != 0:          # 消除0 将已转换的字符串压入栈
                stack.append(i)
        if stack[0] == '-':     # 负号情况下 栈底为-号 将其删掉 补到栈顶
            stack.pop(0)
            stack.append('-')
        s = int(''.join(stack[::-1])) # 栈反转正好是反转的数字

        if s >= 2147483647 or s <= -2147483648: # 判断溢出情况
            return 0
        return s

罗马数字转整数(easy)

分析题目,只有在遇到特殊情况时,两个字符中左边的字符小于右边的字符,且等于右边的字符代表的数减左边字符代表的数。 比如 CM 等于 1000 - 1001000−100,XC 等于 100 - 10100−10...

其他情况就直接加就行了

那么我们只需要读取输入 遍历hashmap 判断是否需要减 就可以了

class Solution:
    def romanToInt(self, s: str) -> int:
        m = {'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000}
        result = 0

        for i in range(len(s)):
            if i < len(s)-1 and m[s[i]] < m[s[i+1]]:
                result -= m[s[i]]
            else:
                result += m[s[i]]

        return result

最长公共前缀

python两种让你拍大腿的解法,时间复杂度你想象不到,短小精悍。
1、利用python的max()和min(),在Python里字符串是可以比较的,按照ascII值排,举例abb, aba,abac,最大为abb,最小为aba。所以只需要比较最大最小的公共前缀就是整个数组的公共前缀

def longestCommonPrefix(self, strs):
   if not strs: return ""
   s1 = min(strs)
   s2 = max(strs)
   for i,x in enumerate(s1):
       if x != s2[i]:
           return s2[:i]
   return s1

2、利用python的zip函数,把str看成list然后把输入看成二维数组,左对齐纵向压缩,然后把每项利用集合去重,之后遍历list中找到元素长度大于1之前的就是公共前缀

def longestCommonPrefix(self, strs):
   if not strs: return ""
   ss = list(map(set, zip(*strs)))
   res = ""
   for i, x in enumerate(ss):
       x = list(x)
       if len(x) > 1:
           break
       res = res + x[0]
   return res
posted @ 2021-01-24 21:36  twosmi1e  阅读(117)  评论(0编辑  收藏  举报