• leetcode刷题 166~


    题目166

    分数到小数

    给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以字符串形式返回小数。

    如果小数部分为循环小数,则将循环的部分括在括号内。

    思路

    长除法,考虑负数/循环小数/整数等多种情况

    实现

    import collections
    class Solution:
        def fractionToDecimal(self, numerator: int, denominator: int) -> str:
            l = ''
            if numerator*denominator <0:
                numerator = abs(numerator)
                denominator = abs(denominator)
                l = '-'
            visied = collections.OrderedDict()
            pos = numerator // denominator
            left = numerator % denominator
            flag = False
            begin = None
            if left == 0:
                return l+str(pos)
            # visied[numerator] = pos
            while left != 0:
                num = left *10
                left = num % denominator
                reco = num // denominator
                if num in visied.keys():
                    flag = True
                    begin = num
                    break
                else:
                    visied[num] = reco
            result = ''
            for i in visied.keys():
                if begin == i:
                    result += '(' 
                result += str(visied[i])
            if flag is True:
                result = result + ')'
            result = str(pos) + '.' + result
            return l+result

    题目167

    两数之和

    给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。

    函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。

    说明:

    返回的下标值(index1 和 index2)不是从零开始的。
    你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。

    思路

    双指针法

    实现

    class Solution:
        def twoSum(self, numbers: List[int], target: int) -> List[int]:
            left = 0
            right = len(numbers) -1
            while left < right: 
                Sum = numbers[left] + numbers[right]
                if Sum == target:
                    return left+1,right+1
                elif Sum > target:
                    right -= 1
                else:
                    left +=1

    题目166

    Excel表列名称

    给定一个正整数,返回它在 Excel 表中相对应的列名称。

    例如,

    1 -> A
    2 -> B
    3 -> C
    ...
    26 -> Z
    27 -> AA
    28 -> AB
    ...

    思路

    用除留余数法将数字由 10 进制转换为 26 进制

    实现

    class Solution:
        def convertToTitle(self, n: int) -> str:
            result = ''
            while n != 0:
                n -= 1
                tmp = chr(65 + n % 26)
                result = tmp + result
                n //= 26
            return result

    题目169

    多数元素

    给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。

    你可以假设数组是非空的,并且给定的数组总是存在多数元素。

    思路

    方法思路很多,详见https://leetcode-cn.com/problems/majority-element/solution/duo-shu-yuan-su-by-leetcode-solution/

    摩尔投票法

    实现

    class Solution:
        def majorityElement(self, nums: List[int]) -> int:
            result  = nums[0]
            count = 1
            for i in range(1,len(nums)):
                if count == 0:
                    result = nums[i]
                    count = 1
                else:
                    if nums[i] == result:
                        count += 1
                    else:
                        count -= 1
            return result

    题目171

    excel表列序号

    给定一个Excel表格中的列名称,返回其相应的列序号。

    例如,

    A -> 1
    B -> 2
    C -> 3
    ...
    Z -> 26
    AA -> 27
    AB -> 28
    ..

    思路

    二十六进制

    实现

    class Solution:
        def titleToNumber(self, s: str) -> int:
            result = 0
            for i in s:
                result = result*26
                temp = ord(i) - 64
                result += temp
            return result

    题目172

    阶乘后的零

    给定一个整数 n,返回 n! 结果尾数中零的数量。

    思路

    阶乘到5的倍数才会新增零,遇到25的倍数新增2个零,125三个零,以此类推

    实现

    class Solution:
        def trailingZeroes(self, n: int) -> int:
            result = 0
            index = 5
            while n >= index:
                result += (n // index)
                index *= 5
            return result

    题目173

    二叉搜索树迭代器

    实现一个二叉搜索树迭代器。你将使用二叉搜索树的根节点初始化迭代器。

    调用 next() 将返回二叉搜索树中的下一个最小的数。

    思路

    中序遍历

    实现

    class BSTIterator:
    
        def __init__(self, root: TreeNode): 
            self.stack = []
            
            def helper(node):
                if node.left:
                    helper(node.left)
                self.stack.append(node.val)
                if node.right:
                    helper(node.right)
            if root:
                helper(root)
    
        def next(self) -> int:
            """
            @return the next smallest number
            """
            result =self.stack[0]
            self.stack.remove(self.stack[0])
            return result
    
        def hasNext(self) -> bool:
            """
            @return whether we have a next smallest number
            """
            if self.stack:
                return True
            else:
                return False

    题目187

    重复的DNA

    思路

    1.暴力法,hash表

    2.见leetcode解答,没有看懂 https://leetcode-cn.com/problems/repeated-dna-sequences/solution/zhong-fu-de-dnaxu-lie-by-leetcode/

    实现

    class Solution:
        def findRepeatedDnaSequences(self, s: str) -> List[str]:
            window = set()
            result = set()
            leng = 10
            for i in range(len(s)-leng+1):
                temp = s[i:i+leng]
                if temp in window:
                    result.add(temp)
                window.add(temp)
            return list(result)

    题目189

    旋转数组

    给定一个数组,将数组中的元素向右移动 个位置,其中 是非负数。

    思路

    首先将所有元素反转。然后反转前 k 个元素,再反转后面 nk 个元素

    原始数组 : 1 2 3 4 5 6 7
    反转所有数字后 : 7 6 5 4 3 2 1
    反转前 k 个数字后 : 5 6 7 4 3 2 1
    反转后 n-k 个数字后 : 5 6 7 1 2 3 4 --> 结果

    实现

    class Solution:
        def rotate(self, nums: List[int], k: int) -> None:
            """
            Do not return anything, modify nums in-place instead.
            """
            k = k%len(nums)
            nums.reverse()
            nums[:k] = nums[:k][::-1]
            nums[k:] = nums[k:][::-1]

    题目190

    颠倒二进制位

    颠倒给定的 32 位无符号整数的二进制位。

    示例 1:

    输入: 00000010100101000001111010011100
    输出: 00111001011110000010100101000000
    解释: 输入的二进制串 00000010100101000001111010011100 表示无符号整数 43261596,
    因此返回 964176192,其二进制表示形式为 00111001011110000010100101000000。

    思路

    实现

    class Solution:
        def reverseBits(self, n: int) -> int:
            result = 0
            num = 0
            while num != 32:
                result = result*2 +(n % 2)
                n = n//2
                num += 1
            return result

    题目191

    位1的个数

    编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。

    思路

    实现

    class Solution:
        def hammingWeight(self, n: int) -> int:
            count = 0
            mask = 1
            num = 0
            while num != 32:
                if n & mask !=0:
                    count += 1
                mask <<= 1
                num += 1
            return count

    题目198

    打家劫舍

    你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。

    给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。

    思路

    动态规划

    实现

    class Solution:
        def rob(self, nums: List[int]) -> int:
            if not nums:
                return 0
            l = len(nums)
            if l ==1 :
                return nums[0]
            result = [0 for _ in range(l)]
            result[0] = nums[0]
            result[1] = nums[1]
            res = max(nums[0],nums[1])
            temp = result[0]
            for i in range(2,l):
                result[i] = nums[i] + temp
                if result[i] > res:
                    res = result[i]
                if result[i-1] > temp:
                    temp = result[i -1]  
            return res

    题目199

    二叉树的右视图

    给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。

    思路

    广度优先遍历/深度优先遍历

    实现

    from collections import deque
    class Solution:
        def rightSideView(self, root: TreeNode) -> List[int]:
            if not root:
                return []
            queue = deque()
            queue.append((root,0))
            result = dict()
            while queue:
                node,depth = queue.popleft()
                result[depth] = node.val
                if node.left:
                    queue.append((node.left,depth+1))        
                if node.right:
                    queue.append((node.right,depth+1))
            return list(result.values())

    题目200

    岛屿数量

    给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。

    岛屿总是被水包围,并且每座岛屿只能由水平方向或竖直方向上相邻的陆地连接形成。

    此外,你可以假设该网格的四条边均被水包围。

    示例 1:

    输入:
    [
    ['1','1','1','1','0'],
    ['1','1','0','1','0'],
    ['1','1','0','0','0'],
    ['0','0','0','0','0']
    ]
    输出: 1

    思路

    深度优先遍历

    实现

    class Solution:
        def numIslands(self, grid: List[List[str]]) -> int:
            row = len(grid)
            if row == 0:
                return 0
            col = len(grid[0])
            result = 0
            for i in range(row):
                for j in range(col):
                    if grid[i][j] == '1':
                        result += 1
                        self.dfs(grid,i,j)
            return result
    
        def dfs(self, grid, i, j):
            grid[i][j] = '0'
            row, col = len(grid), len(grid[0])
            for x, y in [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]:
                if 0 <= x < row and 0 <= y < col and grid[x][y] == "1":
                    self.dfs(grid, x, y)
       

    题目201

    数字范围按位与

    给定范围 [m, n],其中 0 <= m <= n <= 2147483647,返回此范围内所有数字的按位与(包含 m, n 两端点)。

    思路

    参考的官方答案:问题等效于问题给定两个整数,我们要找到它们对应的二进制字符串的公共前缀。

    1.位移

    将两个数字不断向右移动,直到数字相等,即数字被缩减为它们的公共前缀。然后,通过将公共前缀向左移动,将零添加到公共前缀的右边以获得最终结果。

    2.Brian Kernighan 算法

    Brian Kernighan 算法的关键在于我们每次对 number和 number-1之间进行按位与运算后,number 中最右边的 1会被抹去变成 0。可以对数字 nn迭代地应用上述技巧,清除最右边的 1,直到它小于或等于 m,此时非公共前缀部分的 1均被消去。

    实现

    1.
    class Solution:
        def rangeBitwiseAnd(self, m: int, n: int) -> int:
            shift = 0   
            # 找到公共前缀
            while m < n:
                m = m >> 1
                n = n >> 1
                shift += 1
            return m << shift
    
    2.
    class Solution:
        def rangeBitwiseAnd(self, m: int, n: int) -> int:
            while m < n:
                # 抹去最右边的 1
                n = n & (n - 1)
            return n

    题目202

    快乐数

    编写一个算法来判断一个数 n 是不是快乐数。

    「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果 可以变为  1,那么这个数就是快乐数。

    如果 n 是快乐数就返回 True ;不是,则返回 False 。

    示例:

    输入:19
    输出:true
    解释:
    1^2 + 9^2 = 82
    8^2 + 2^2 = 68
    6^2 + 8^2 = 100
    1^2 + 0^2 + 0^2 = 1

    思路

    实现

    class Solution:
        def isHappy(self, n: int) -> bool:
            def get_next(n: int) -> int:
                temp = 0
                while n > 0:
                    n, digit = divmod(n, 10)
                    temp += digit ** 2
                return temp
            visited = set()
            while n != 1 and n not in visited:
                visited.add(n)
                n = get_next(n)
            return n==1

    题目203

    移除链表元素

    删除链表中等于给定值 val 的所有节点。

    思路实现

    class Solution:
        def removeElements(self, head: ListNode, val: int) -> ListNode:
            result = ListNode(None)
            result.next = head
            before = result
            while head:
                if head.val != val:
                    before = head
                else:
                    before.next = head.next
                head = head.next
            return result.next

    题目204

    计数质数

    统计所有小于非负整数 n 的质数的数量。

    思路

    厄拉多塞筛法:

    要得到自然数n以内的全部质数,必须把不大于根号n的所有质数的倍数剔除,剩下的就是质数。

    实现

    class Solution:
        def countPrimes(self, n: int) -> int:
            if n < 2: return 0
            primes = [1 for _ in range(n)]
            primes[0] = primes[1] = 0
            for i in range(2,int(n**0.5)+1):
                j = i
                while i * j < n:
                    primes[i*j] = 0
                    j += 1
            return sum(primes)

    题目205

    同构字符串

    给定两个字符串 s 和 t,判断它们是否是同构的。

    如果 s 中的字符可以被替换得到 t ,那么这两个字符串是同构的。

    所有出现的字符都必须用另一个字符替换,同时保留字符的顺序。两个字符不能映射到同一个字符上,但字符可以映射自己本身。

    思路

    字典

    实现

    class Solution:
        def isIsomorphic(self, s: str, t: str) -> bool:
            a = dict()
            b = dict()
            for i in range(len(s)):
                a[s[i]] = t[i]
                b[t[i]] = s[i]
            for i in range(len(s)):
                if a[s[i]] != t[i] or b[t[i]] != s[i]:
                    return False
            return True

    题目206

    反转链表

    反转一个单链表。

    思路实现

    class Solution:
        def reverseList(self, head: ListNode) -> ListNode:
            result = None
            while head:
                node = head.next
                head.next = result
                result = head
                head = node
            return result

    题目207

    课程表

    你这个学期必须选修 numCourse 门课程,记为 0 到 numCourse-1 。

    在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们:[0,1]

    给定课程总量以及它们的先决条件,请你判断是否可能完成所有课程的学习?

    示例 1:

    输入: 2, [[1,0]]
    输出: true
    解释: 总共有 2 门课程。学习课程 1 之前,你需要完成课程 0。所以这是可能的。

    思路

    思路很简单,深度优先遍历即可,当遍历到重复的点时,说明出现环,则失败

    实现

    class Solution:
        def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
            on_stack = [False for _ in range(numCourses)]
            visited = [False for _ in range(numCourses)]
            edges = collections.defaultdict(list)
            flag = True
            for info in prerequisites:
                edges[info[0]].append(info[1])
    
            def dfs(cur, on_stack):
                nonlocal flag
                on_stack[cur] = True
                visited[i] = True
                for pre_cour in edges[cur]:
                    if on_stack[pre_cour] is False:
                        if not visited[pre_cour]:
                            dfs(pre_cour,on_stack)
                    else:
                        flag = False
                        return 
                on_stack[cur] = False
                
    
            for i in range(numCourses):
                if not visited[i] and flag:
                    dfs(i,on_stack)
    
            return flag

    效率偏低,可以优化

    题目208

    实现Trie

    实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作。

    示例:

    Trie trie = new Trie();

    trie.insert("apple");
    trie.search("apple"); // 返回 true
    trie.search("app"); // 返回 false
    trie.startsWith("app"); // 返回 true
    trie.insert("app");
    trie.search("app"); // 返回 true

    思路

    Trie 树是一个有根的树,其结点具有以下字段:。

    ·最多 R个指向子结点的链接,其中每个链接对应字母表数据集中的一个字母。本文中假定 R 为 26,小写拉丁字母的数量。

    ·布尔字段,以指定节点是对应键的结尾还是只是键前缀。

    实现

    class Node:
        def __init__(self, val=None ,end = False):
            self.val = val
            self.is_end = end
            self.next = {}
    
    class Trie:
    
        def __init__(self):
            """
            Initialize your data structure here.
            """
            self.root = Node()
    
        def insert(self, word: str) -> None:
            """
            Inserts a word into the trie.
            """
            node = self.root
            for i in word:
                if i not in node.next:
                    node.next[i] = Node(i)
                node = node.next[i]
            node.is_end = True
    
        def search(self, word: str) -> bool:
            """
            Returns if the word is in the trie.
            """
            node = self.root
            for i in word:
                if i not in node.next:
                    return False
                node = node.next[i]
            if node.is_end is False:
                return False
            return True 
    
    
        def startsWith(self, prefix: str) -> bool:
            """
            Returns if there is any word in the trie that starts with the given prefix.
            """
            node = self.root
            for i in prefix:
                if i not in node.next:
                    return False
                node = node.next[i]
            return True
  • 相关阅读:
    linux服务器时间同步
    07_DICTIONARY_ACCESSIBILITY
    Oracle监听静态注册和动态注册
    Oracle安装基本步骤
    笔试面试(2)阿里巴巴2014秋季校园招聘-软件研发工程师笔试题详解
    Global and Local Coordinate Systems
    齐次坐标(Homogeneous Coordinates)
    朴素贝叶斯分类器的应用
    图像数据到网格数据-1——MarchingCubes算法
    PCL源码剖析之MarchingCubes算法
  • 原文地址:https://www.cnblogs.com/mgdzy/p/13743896.html
Copyright © 2020-2023  润新知