剑指Offer and Leetcode刷题总结之xx:其他

Leetcode07:整数反转

题目:给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。

基本思路:判断正负,保留符号,利用商以及余数,反向计算;(重点是考虑溢出问题)

1. 当数字为正数时,max_value = 2**31 - 1的末尾数为7;当数字为负数时, min_value = -2**31末尾数为8;

2. 在达到与max_value相同的位数之前提前截止;

class Solution(object):
    def reverse(self, x):
        """
        :type x: int
        :rtype: int
        """
        label = True
        output = 0
        max_value = 2**31 - 1
        min_value = -2**31
        if x < 0:
            label = False
            x = abs(x)
        while x != 0:
            pop = x % 10
            """重点: 考虑溢出情况, 在得出结果的上一步就必须判断是否计算会溢出"""
            if (label == True) and ((output > max_value // 10) or (output == max_value // 10 and pop > 7)):
                return 0
            if (label == False) and ((output > max_value // 10) or (output == max_value // 10 and pop > 8)): 
                return 0
            """不考虑溢出情况, 仅需要以下语句"""
            output = output * 10 + pop
            x = x // 10
        return output if label == True else -output    

Leetcode17:电话号码的字母组合

题目:给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

示例输入:"23" 输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].

基本思路:遍历digit,将当前result中的元素全部pop出来,再逐一跟digit中所对应的字母组合;

时间复杂度:O(3^M * 4^N)--M为输入中对应字母为3个的数字的个数;N为input中对应字母为4个的数字的个数;

空间复杂度:O(1) --没有用到额外的空间;

class Solution(object):
    def letterCombinations(self, digits):
        """
        :type digits: str
        :rtype: List[str]
        """
        import collections
        mapping = ['', '', 'abc', 'def', 'ghi', 'jkl', 'mno', 'pqrs', 'tuv', 'wxyz']
        result = collections.deque([''])
        for d in digits:
            for _ in range(len(result)):
                prev = result.popleft()           # 逐个把result中的元素pop出来
                for letter in mapping[int(d)]:
                    result.append(prev + letter)  # 接着凭借上新的元素再压入进去
        return list(result) if digits else []

Leetcode20:有效的括号

题目:给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。有效字符串需满足:左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。注意空字符串可被认为是有效字符串。

基本思路

class Solution(object):
    def isValid(self, s):
        """
        :type s: str
        :rtype: bool
        """
        sta = [] # 维护一个stack
        dic = {')':'(', ']':'[', '}':'{'} # 把成对括号都存入dic中
        for e in s:
            if e in dic:
                top_e = sta.pop() if sta else '#'
                if top_e != dic[e]:
                    return False
            else:
                sta.append(e)
        return not sta

Leetcode56:合并区间

题目:给出一个区间的集合,请合并所有重叠的区间。

示例:输入: [[1,3],[2,6],[8,10],[15,18]];输出: [[1,6],[8,10],[15,18]];解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].

基本思路:先sort();如果不能合并,则append m,同时更新m = n,继续pop n;如果可以合并,则合并为m,再继续pop n;

class Solution(object):
    def merge(self, intervals):
        """
        :type intervals: List[List[int]]
        :rtype: List[List[int]]
        """
        size = len(intervals)
        if size <= 1: return intervals
        intervals.sort()   # 一定要加sort() 否则是乱的;应付testcase:[[2,3],[4,5],[6,7],[8,9],[1,10]]
        m = intervals.pop(0)
        ans = []
        while intervals:
            n = intervals.pop(0)
            if n[0] > m[1] or m[0] > n[1]: # m和n没有重叠区域,此次不发生合并,将m append进入,更新m = n
                ans.append(m)
                m = n
            else:                          # 一定有重叠区域,此次发生合并,m and n合并为m,继续pop n出来
                tmp = [min(m[0], n[0]), max(m[1], n[1])]
                m = tmp                
        ans.append(m)
        return ans

Leetcode233:数字 1 的个数(参考题解)

题目:给定一个整数 n,计算所有小于等于 n 的非负整数中数字 1 出现的个数。

示例输入: 13 输出: 6 解释: 数字 1 出现在以下数字中: 1, 10, 11, 12, 13 。

基本思路:时间复杂度为输入n为位数,10^k = n --> k = logn;空间复杂度O(1)

1. 主要思路:设定整数点(如1、10、100等等)作为位置点i(对应n的各位、十位、百位等等),分别对每个数位上有多少包含1的点进行分析;

2. 根据设定的整数位置,对n进行分割,分为两部分,高位n/i,低位n%i;

3. 当i表示百位,且百位对应的数>=2,如n=31456,i=100,则a=314,b=56,此时百位为1的次数有a/10+1=32(最高两位0~31),每一次都包含100个连续的点,即共有(a%10+1)*100个点的百位为1;

4. 当i表示百位,且百位对应的数为1,如n=31156,i=100,则a=311,b=56,此时百位对应的就是1,则共有a%10(最高两位0-30)次是包含100个连续点,当最高两位为31(即a=311),本次只对应局部点00~56,共b+1次,所有点加起来共有(a%10*100)+(b+1),这些点百位对应为1;

5. 当i表示百位,且百位对应的数为0,如n=31056,i=100,则a=310,b=56,此时百位为1的次数有a/10=31(最高两位0~30);

6. 综合以上三种情况,当百位对应0或>=2时,有(a+8)/10次包含所有100个点,还有当百位为1(a%10==1),需要增加局部点b+1;

7. 之所以补8,是因为当百位为0,则a/10==(a+8)/10,当百位>=2,补8会产生进位位,效果等同于(a/10+1);

class Solution(object):
    def countDigitOne(self, n):
        """
        :type n: int
        :rtype: int
        """
        ans, i = 0, 1
        while i <= n:
            hi, lo = n / i, n % i 
            ans += (hi + 8) / 10 * i + (hi % 10 == 1) * (lo + 1)
            i *= 10
        return ans

 

你可能感兴趣的:(剑指Offer and Leetcode刷题总结之xx:其他)