leetcode面试刷题

github网址:https://github.com/yflfly

1、面试题39. 数组中出现次数超过一半的数字

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
输出: 2
 

class Solution:
    def majorityElement(self, nums: List[int]) -> int:
        dict1 = {}
        for each in nums:
            if each not in dict1:
                dict1[each] = 1
            else:
                dict1[each] += 1
        length = len(nums)//2
        for each in dict1:
            if dict1[each] > length:
                return each


2、面试题50. 第一个只出现一次的字符
在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。
示例:
s = "abaccdeff"
返回 "b"
s = ""
返回 " "
 

class Solution:
    def firstUniqChar(self, s: str) -> str:
        d1 = {}
        for each in s:
            if each not in d1:
                d1[each] = 1
            else:
                d1[each] += 1
        for key in s:
            if d1[key] == 1:
                return key
        return ' '


3、面试题15. 二进制中1的个数

请实现一个函数,输入一个整数,输出该数二进制表示中 1 的个数。例如,把 9 表示成二进制是 1001,有 2 位是 1。因此,如果输入 9,则该函数输出 2。
示例 1:
输入:00000000000000000000000000001011
输出:3
解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。
示例 2:
输入:00000000000000000000000010000000
输出:1
解释:输入的二进制串 00000000000000000000000010000000 中,共有一位为 '1'。
示例 3:
输入:11111111111111111111111111111101
输出:31
解释:输入的二进制串 11111111111111111111111111111101 中,共有 31 位为 '1'。

class Solution:
    def hammingWeight(self, n: int) -> int:
        return list(str(bin(n))).count('1')


4、面试题18. 删除链表的节点
给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。
返回删除后的链表的头节点。
注意:此题对比原题有改动
示例 1:
输入: head = [4,5,1,9], val = 5
输出: [4,1,9]
解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.
示例 2:
输入: head = [4,5,1,9], val = 1
输出: [4,5,9]
解释: 给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9.

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def deleteNode(self, head: ListNode, val: int) -> ListNode:
        pre = head
        if head.val == val:
            return head.next
        while pre.next:
            if pre.next.val == val:
                pre.next = pre.next.next
            else:
                pre = pre.next
        return head


5、面试题11. 旋转数组的最小数字

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。
示例 1:
输入:[3,4,5,1,2]
输出:1
示例 2:
输入:[2,2,2,0,1]
输出:0
 

# 自己的代码
class Solution:
    def minArray(self, numbers: List[int]) -> int:
        return min(numbers)
# 大神的代码:二分查找
class Solution:
    def minArray(self, numbers: List[int]) -> int:
        if not numbers: return
        start, end = 0, len(numbers) - 1
        while start < end:
            middle = (start + end) // 2
            if numbers[middle] > numbers[end]: start = middle + 1
            elif numbers[middle] < numbers[end]: end = middle
            # 其实这个end-=1很巧妙,因为相等的时候我们无法判断要往哪个方向缩小
            # 所以索性就缩小numbers的长度。
            else: end -= 1
        return numbers[start]


6、
'''
21. 合并两个有序链表
将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 
示例:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
22
'''
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        result_node = ListNode(0)
        node = result_node
        head1 = l1
        head2 = l2
        while (head1 and head2):
            if head1.val < head2.val:
                node.next = head1
                head1 = head1.next
                node = node.next
            else:
                node.next = head2
                head2 = head2.next
                node = node.next
        while head1:
            node.next = head1
            head1 = head1.next
            node = node.next
        while head2:
            node.next = head2
            head2 = head2.next
            node = node.next
        return result_node.next


7、'''
290. 单词规律
给定一种规律 pattern 和一个字符串 str ,判断 str 是否遵循相同的规律。
这里的 遵循 指完全匹配,例如, pattern 里的每个字母和字符串 str 中的每个非空单词之间存在着双向连接的对应规律。
示例1:
输入: pattern = "abba", str = "dog cat cat dog"
输出: true
示例 2:
输入:pattern = "abba", str = "dog cat cat fish"
输出: false
示例 3:
输入: pattern = "aaaa", str = "dog cat cat dog"
输出: false
示例 4:
输入: pattern = "abba", str = "dog dog dog dog"
输出: false
说明:
你可以假设 pattern 只包含小写字母, str 包含了由单个空格分隔的小写字母。    
'''
class Solution:
    def wordPattern(self, pattern: str, str: str) -> bool:
        l1 = list(pattern)
        l2 = str.split()
        dict1 = {}
        if len(l1) != len(l2):
            return False
        for i in range(len(l1)):
            if l1[i] not in dict1:
                dict1[l1[i]] = l2[i]
            else:
                if dict1[l1[i]] != l2[i]:
                    return False
        if len(list(set(dict1.values()))) != len(dict1.values()):
            return False
        return True
8、'''
219. 存在重复元素 II
给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums [i] = nums [j],并且 i 和 j 的差的 绝对值 至多为 k。
示例 1:
输入: nums = [1,2,3,1], k = 3
输出: true
示例 2:
输入: nums = [1,0,1,1], k = 1
输出: true
示例 3:
输入: nums = [1,2,3,1,2,3], k = 2
输出: false
'''
# 下面代码会报超出时间限制
class Solution:
    def containsNearbyDuplicate(self, nums: List[int], k: int) -> bool:
        for i in range(len(nums)):
            for m in range(k):
                if i+m+1 < len(nums):
                    if nums[i] == nums[i+m+1]:
                        return True
        return False
# 下面的代码通过,for循环使用的少可以减少运行时间
class Solution:
    def containsNearbyDuplicate(self, nums: List[int], k: int) -> bool:
        dict1 = {}
        for i in range(len(nums)):
            if nums[i] in dict1:
                if i-dict1[nums[i]] <= k:
                    return True
            dict1[nums[i]] = i
        return False
9、# coding:utf-8
'''
面试题 01.05. 一次编辑
字符串有三种编辑操作:插入一个字符、删除一个字符或者替换一个字符。 给定两个字符串,编写一个函数判定它们是否只需要一次(或者零次)编辑。
示例 1:
输入:
first = "pale"
second = "ple"
输出: True
示例 2:
输入:
first = "pales"
second = "pal"
输出: False

'''
class Solution:
    def oneEditAway(self, first: str, second: str) -> bool:
        if abs(len(list(first))-len(list(second))) > 1:
            return False
        flag = 0
        if len(list(first)) == len(list(second)):
            for i in range(len(first)):
                if first[i] != second[i]:
                    flag += 1
                if flag > 1:
                    return False
            return True
        else:
            min_ = first if len(first) == min(len(first),len(second)) else second
            max_ = first if min_== second else second
            linshi = min_
            if max_.find(min_) != -1:
                return True
            for j in range(len(max_)):
                if linshi[j] != max_[j]:
                    flag += 1
                    linshi = linshi[:j]+max_[j]+linshi[j:]
                if flag > 1:
                    return False
            return True
10、
'''
203. 移除链表元素
删除链表中等于给定值 val 的所有节点。
示例:
输入: 1->2->6->3->4->5->6, val = 6
输出: 1->2->3->4->5
'''
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def removeElements(self, head: ListNode, val: int) -> ListNode:
        cur_1 = ListNode(0)
        cur = cur_1
        while head:
            if head.val == val:
                head = head.next
            else:
                cur.next = ListNode(head.val)
                cur = cur.next
                head = head.next
        return cur_1.next
11、
'''
441. 排列硬币
1、你总共有 n 枚硬币,你需要将它们摆成一个阶梯形状,第 k 行就必须正好有 k 枚硬币。
给定一个数字 n,找出可形成完整阶梯行的总行数。
n 是一个非负整数,并且在32位有符号整型的范围内。
示例 1:
n = 5
硬币可排列成以下几行:
¤
¤ ¤
¤ ¤
因为第三行不完整,所以返回2.
示例 2:
n = 8
硬币可排列成以下几行:
¤
¤ ¤
¤ ¤ ¤
¤ ¤
因为第四行不完整,所以返回3.
代码如下所示:
'''
from math import sqrt, floor
class Solution:
    def arrangeCoins(self, n: int) -> int:
        return floor(sqrt(1/4+2*n)-1/2)
12、
'''
面试题53 - II. 0~n-1中缺失的数字
一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字。
示例 1:
输入: [0,1,3]
输出: 2
示例 2:
输入: [0,1,2,3,4,5,6,7,9]
输出: 8
'''
class Solution:
    def missingNumber(self, nums: List[int]) -> int:
        list1 = [i for i in range(len(nums)+1)]
        return sum(list1)-sum(nums)

13、
'''
2. 两数相加
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807
'''
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
            list1 = []
            list2 = []
            l1_ = l1
            l2_ = l2
            while l1_:
                list1.append(l1_.val)
                l1_ = l1_.next
            while l2_:
                list2.append(l2_.val)
                l2_ = l2_.next
            int1 = 0
            for i in range(len(list1)-1,-1,-1):
                int1 += list1[i] *10**i
            int2 = 0
            for i in range(len(list2)-1,-1,-1):
                int2 += list2[i] *10**i
            c = int1 + int2
            c_list = list(str(c))
            cur_ = ListNode(0)
            cur = cur_
            for i in range(len(c_list) - 1, -1, -1):
                linshi = ListNode(0)
                linshi.val = int(c_list[i])
                cur.next = linshi
                cur = cur.next

            return cur_.next
'''
17. 电话号码的字母组合
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例:
输入:"23"
输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].

'''


class Solution:
    def letterCombinations(self, digits: str) -> List[str]:
        dict1 = {'2': 'abc', '3': 'def', '4': 'ghi', '5': 'jkl', '6': 'mno', '7': 'pqrs', '8': 'tuv', '9': 'wxyz'}
        if len(digits) == 0:
            return []
        if len(digits) == 1:
            return list(dict1[digits[0]])
        res = self.letterCombinations(digits[1:])
        res_zuhe = []
        for i in res:
            for j in dict1[digits[0]]:
                res_zuhe.append(j+i)
        return res_zuhe

'''
面试题56 - I. 数组中数字出现的次数
一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
示例 1:
输入:nums = [4,1,4,6]
输出:[1,6] 或 [6,1]
示例 2:
输入:nums = [1,2,10,4,1,4,3,3]
输出:[2,10] 或 [10,2]
'''


class Solution:
    def singleNumbers(self, nums: List[int]) -> List[int]:
        dict1 = {}
        for each in nums:
            if each not in dict1:
                dict1[each] = 1
            else:
                dict1[each] += 1
        list1 = []
        for each in dict1:
            if dict1[each] == 1:
                list1.append(each)
        return list1

'''
88. 合并两个有序数组
给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。
说明:
初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。
你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
示例:
输入:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6],       n = 3

输出: [1,2,2,3,5,6]
'''


class Solution:
    def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
        """
        Do not return anything, modify nums1 in-place instead.
        """

        for i in range(len(nums2)):
            nums1[i + m] = nums2[i]
        nums1 = nums1.sort()


# 下面的方法也可以实现功能,但是提交不通过,本题是要不改变nums1的前提下通过,且不需要return语句
def merge(nums1, m, nums2, n):
    """
    Do not return anything, modify nums1 in-place instead.
    """
    nums1 = nums1[:m]
    for i in range(len(nums2)):
        # print(nums1)
        for j in range(len(nums1)):
            if nums2[i] == 'False':
                continue
            if nums2[i] <= nums1[j]:
                nums1.insert(j, nums2[i])
                nums2[i] = 'False'
                break
        if nums2[i] != 'False':
            nums1.append(nums2[i])
    return nums1

'''
15. 三数之和
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例:
给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[
  [-1, 0, 1],
  [-1, -1, 2]
]
'''


class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        result = []
        if len(nums) < 3:
            return []
        nums.sort()
        n = len(nums)
        for i in range(len(nums) - 2):
            if nums[i] > 0:
                break
            left, right = i + 1, n - 1
            if i > 0 and nums[i] == nums[i - 1]:
                continue
            while left < right:
                s = nums[i] + nums[left] + nums[right]
                if s < 0:
                    left += 1
                    while left < right and nums[left] == nums[left - 1]:
                        left += 1
                elif s > 0:
                    right = right - 1
                    while left < right and nums[right] == nums[right + 1]:
                        right = right - 1
                else:
                    result.append([nums[i], nums[left], nums[right]])
                    left += 1
                    right = right -1
                    while left < right and nums[left] == nums[left - 1]:
                        left += 1
                    while left < right and nums[right] == nums[right + 1]:
                        right = right - 1
        return result
'''
709. 转换成小写字母
实现函数 ToLowerCase(),该函数接收一个字符串参数 str,并将该字符串中的大写字母转换成小写字母,之后返回新的字符串。
示例 1:
输入: "Hello"
输出: "hello"
示例 2:
输入: "here"
输出: "here"
示例 3:
输入: "LOVELY"
输出: "lovely"
'''


class Solution:
    def toLowerCase(self, str: str) -> str:
        return str.lower()

# coding:utf-8
'''
面试题 17.07. 婴儿名字
每年,政府都会公布一万个最常见的婴儿名字和它们出现的频率,也就是同名婴儿的数量。有些名字有多种拼法,例如,John 和 Jon 本质上是相同的名字,但被当成了两个名字公布出来。给定两个列表,一个是名字及对应的频率,另一个是本质相同的名字对。设计一个算法打印出每个真实名字的实际频率。注意,如果 John 和 Jon 是相同的,并且 Jon 和 Johnny 相同,则 John 与 Johnny 也相同,即它们有传递和对称性。
在结果列表中,选择字典序最小的名字作为真实名字。
示例:
输入:names = ["John(15)","Jon(12)","Chris(13)","Kris(4)","Christopher(19)"], synonyms = ["(Jon,John)","(John,Johnny)","(Chris,Kris)","(Chris,Christopher)"]
输出:["John(27)","Chris(36)"]
'''

import collections


def trulyMostPopular(names, synonyms):
    list1 = []
    for each in synonyms:
        a, b = each[1:-1].split(',')
        if list1 == []:
            list1.append([a, b])
        else:
            tag = 0
            for i in range(len(list1)):
                if a in list1[i]:
                    list1[i].append(b)
                    tag = 1
                    break
                elif b in list1[i]:
                    list1[i].append(a)
                    tag = 1
                    break
            if tag == 0:
                list1.append([a, b])
    dict1 = collections.OrderedDict()
    dict_res = collections.OrderedDict()
    for elem in names:
        str1, num1 = elem.split('(')[0], int(elem.split('(')[-1].split(')')[0])
        dict1[str1] = num1
    for each in list1:
        tag = ''
        for i in range(len(each)):
            if not dict_res:
                if each[i] in dict1:
                    dict_res[each[i]] = dict1[each[i]]
                    tag = each[i]
            else:
                if tag != '':
                    if each[i] in dict1:
                        dict_res[tag] += dict1[each[i]]
                else:
                    if each[i] in dict1:
                        dict_res[each[i]] = dict1[each[i]]
                        tag = each[i]
    list_res = []
    for key in dict_res.keys():
        list_res.append(key + '(' + str(dict_res[key]) + ')')
    return list_res

names = ["John(15)", "Jon(12)", "Chris(13)", "Kris(4)", "Christopher(19)"]
synonyms = ["(Jon,John)", "(John,Johnny)", "(Chris,Kris)", "(Chris,Christopher)"]
trulyMostPopular(names, synonyms)

# coding:utf-8
'''
41. 缺失的第一个正数
给你一个未排序的整数数组,请你找出其中没有出现的最小的正整数。
示例 1:
输入: [1,2,0]
输出: 3
示例 2:
输入: [3,4,-1,1]
输出: 2
示例 3:
输入: [7,8,9,11,12]
输出: 1
'''


class Solution:
    def firstMissingPositive(self, nums: List[int]) -> int:
        nums.sort()
        if not nums:
            return 1
        for i in range(1, len(nums)+1):
            if i not in nums:
                return i
        return len(nums)+1
# coding:utf-8
'''
3. 无重复字符的最长子串
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
'''


class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        if len(s) == 0:
            return 0
        if len(list(set(list(s)))) == 1:
            return 1
        dict1 = {}
        for i in range(len(s)):
            str1 = s[i]
            tag = 0
            for j in range(i + 1, len(s)):
                if s[j] not in str1:
                    str1 = str1 + s[j]
                else:
                    if str1 not in dict1:
                        dict1[str1] = len(str1)
                    tag = 1
                    break
            if tag == 0:
                dict1[str1] = len(str1)
        list1 = dict1.values()
        max1 = 0
        for each in list1:
            if each > max1:
                max1 = each
        return max1

'''
1410. HTML 实体解析器
「HTML 实体解析器」 是一种特殊的解析器,它将 HTML 代码作为输入,并用字符本身替换掉所有这些特殊的字符实体。
HTML 里这些特殊字符和它们对应的字符实体包括:
双引号:字符实体为 " ,对应的字符是 " 。
单引号:字符实体为 ' ,对应的字符是 ' 。
与符号:字符实体为 & ,对应对的字符是 & 。
大于号:字符实体为 > ,对应的字符是 > 。
小于号:字符实体为 < ,对应的字符是 < 。
斜线号:字符实体为 ⁄ ,对应的字符是 / 。
给你输入字符串 text ,请你实现一个 HTML 实体解析器,返回解析器解析后的结果。
示例 1:
输入:text = "& is an HTML entity but &ambassador; is not."
输出:"& is an HTML entity but &ambassador; is not."
解释:解析器把字符实体 & 用 & 替换
示例 2:
输入:text = "and I quote: "...""
输出:"and I quote: \"...\""
示例 3:
输入:text = "Stay home! Practice on Leetcode :)"
输出:"Stay home! Practice on Leetcode :)"
示例 4:
输入:text = "x > y && x < y is always false"
输出:"x > y && x < y is always false"
示例 5:
输入:text = "leetcode.com⁄problemset⁄all"
输出:"leetcode.com/problemset/all"
'''


class Solution:
    def entityParser(self, text: str) -> str:
        dict1 = {'"': '\"', ''': "\'", '>': '>', '<': '<', '⁄': '/', '&': '&'}
        for key in dict1:
            text = text.replace(key, dict1[key])
        return text
'''
1408. 数组中的字符串匹配
给你一个字符串数组 words ,数组中的每个字符串都可以看作是一个单词。请你按 任意 顺序返回 words 中是其他单词的子字符串的所有单词。
如果你可以删除 words[j] 最左侧和/或最右侧的若干字符得到 word[i] ,那么字符串 words[i] 就是 words[j] 的一个子字符串。
示例 1:
输入:words = ["mass","as","hero","superhero"]
输出:["as","hero"]
解释:"as" 是 "mass" 的子字符串,"hero" 是 "superhero" 的子字符串。
["hero","as"] 也是有效的答案。
示例 2:
输入:words = ["leetcode","et","code"]
输出:["et","code"]
解释:"et" 和 "code" 都是 "leetcode" 的子字符串。
示例 3:
输入:words = ["blue","green","bu"]
输出:[]
'''

class Solution:
    def stringMatching(self, words: List[str]) -> List[str]:
        list1 = []
        for each in words:
            for each2 in words:
                if each != each2 and each in each2:
                    list1.append(each)
                    break
        return list1
# coding:utf-8
'''  尝试ing
722. 删除注释
给一个 C++ 程序,删除程序中的注释。这个程序source是一个数组,其中source[i]表示第i行源码。 这表示每行源码由\n分隔。
在 C++ 中有两种注释风格,行内注释和块注释。
字符串// 表示行注释,表示//和其右侧的其余字符应该被忽略。
字符串/* 表示一个块注释,它表示直到*/的下一个(非重叠)出现的所有字符都应该被忽略。(阅读顺序为从左到右)非重叠是指,字符串/*/并没有结束块注释,因为注释的结尾与开头相重叠。
第一个有效注释优先于其他注释:如果字符串//出现在块注释中会被忽略。 同样,如果字符串/*出现在行或块注释中也会被忽略。
如果一行在删除注释之后变为空字符串,那么不要输出该行。即,答案列表中的每个字符串都是非空的。
样例中没有控制字符,单引号或双引号字符。比如,source = "string s = "/* Not a comment. */";" 不会出现在测试样例里。(此外,没有其他内容(如定义或宏)会干扰注释。)
我们保证每一个块注释最终都会被闭合, 所以在行或块注释之外的/*总是开始新的注释。
最后,隐式换行符可以通过块注释删除。 有关详细信息,请参阅下面的示例。
从源代码中删除注释后,需要以相同的格式返回源代码。
示例 1:
输入:
source = ["/*Test program */", "int main()", "{ ", "  // variable declaration ", "int a, b, c;", "/* This is a test", "   multiline  ", "   comment for ", "   testing */", "a = b + c;", "}"]
示例代码可以编排成这样:
/*Test program */
int main()
{
  // variable declaration
int a, b, c;
/* This is a test
   multiline
   comment for
   testing */
a = b + c;
}
输出: ["int main()","{ ","  ","int a, b, c;","a = b + c;","}"]
编排后:
int main()
{

int a, b, c;
a = b + c;
}

解释:
第 1 行和第 6-9 行的字符串 /* 表示块注释。第 4 行的字符串 // 表示行注释。
示例 2:

输入:
source = ["a/*comment", "line", "more_comment*/b"]
输出: ["ab"]
解释: 原始的 source 字符串是 "a/*comment\nline\nmore_comment*/b", 其中我们用粗体显示了换行符。删除注释后,隐含的换行符被删除,留下字符串 "ab" 用换行符分隔成数组时就是 ["ab"].
'''


def removeComments(source):
    list1 = []
    tag = 0
    for each in source:
        if each.find('//') != -1 and tag == 0:
            if each.find('//') < each.find('/*'):
                list1.append(each.split('//')[0])
                continue
            if each.find('/*') == -1:
                list1.append(each.split('//')[0])
                continue

        if each.find('/*') != -1 and each.find('*/') != -1:
            if each.split('/*')[0]+each.split('*/')[-1]:
                list1.append(each.split('/*')[0]+each.split('*/')[-1])
            continue
        if each.find('/*') != -1:
            tag = 1
            if each.split('/*')[0]:
                list1.append(each.split('/*')[0])
            continue
        if each.find('*/') != -1:
            tag = 0
            if each.split('*/')[-1]:
                list1[-1] = list1[-1]+each.split('*/')[-1]
            continue
        if tag == 1:
            continue
        list1.append(each)
    return list1


# source = ["/*Test program */", "int main()", "{ ", "  // variable declaration ", "int a, b, c;", "/* This is a test","   multiline  ", "   comment for ", "   testing */", "a = b + c;", "}"]
# source = ["a/*comment", "line", "more_comment*/b"]
source = ["void func(int k) {", "// this function does nothing /*", "   k = k*2/4;", "   k = k/2;*/", "}"]
# ["void func(int k) {","   k = k*2/4;","   k = k/2;*/","}"]
print(removeComments(source))

# coding:utf-8
'''
53. 最大子序和
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

示例:

输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
'''


class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        maxSum = tempSum = nums[0]
        for num in nums[1:]:
            tempSum = max(num, num + tempSum)
            maxSum = max(maxSum, tempSum)
        return maxSum

# coding:utf-8
'''
819. 最常见的单词
给定一个段落 (paragraph) 和一个禁用单词列表 (banned)。返回出现次数最多,同时不在禁用列表中的单词。
题目保证至少有一个词不在禁用列表中,而且答案唯一。
禁用列表中的单词用小写字母表示,不含标点符号。段落中的单词不区分大小写。答案都是小写字母。
示例:
输入:
paragraph = "Bob hit a ball, the hit BALL flew far after it was hit."
banned = ["hit"]
输出: "ball"
解释:
"hit" 出现了3次,但它是一个禁用的单词。
"ball" 出现了2次 (同时没有其他单词出现2次),所以它是段落里出现次数最多的,且不在禁用列表中的单词。
注意,所有这些单词在段落里不区分大小写,标点符号需要忽略(即使是紧挨着单词也忽略, 比如 "ball,"),
"hit"不是最终的答案,虽然它出现次数更多,但它在禁用单词列表中。
'''


class Solution:
    def mostCommonWord(self, paragraph: str, banned: List[str]) -> str:
        dict1 = {}
        L = paragraph.replace(',', ' ').replace('.', '').replace('!', '').replace('?', '').replace(';', '').replace("'",'').lower()
        for each in L.split():
            linshi = each.lower()
            if linshi not in banned:
                if linshi not in dict1.keys():
                    dict1[linshi] = 1
                else:
                    dict1[linshi] += 1
        max1 = 0
        flag = ''
        for key in dict1.keys():
            if dict1[key] > max1:
                max1 = dict1[key]
                flag = key
        return flag


'''
680. 验证回文字符串 Ⅱ
给定一个非空字符串 s,最多删除一个字符。判断是否能成为回文字符串。

示例 1:

输入: "aba"
输出: True
示例 2:

输入: "abca"
输出: True
解释: 你可以删除c字符。
'''


class Solution:
    def validPalindrome(self, s):
        if s == s[::-1]:
            return True
        l, r = 0, len(s) - 1
        while l < r:
            if s[l] == s[r]:
                l, r = l + 1, r - 1
            else:
                a = s[l + 1: r + 1]
                b = s[l:r]
                return a == a[::-1] or b == b[::-1]

'''
66. 加一
给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
示例 1:
输入: [1,2,3]
输出: [1,2,4]
解释: 输入数组表示数字 123。
示例 2:
输入: [4,3,2,1]
输出: [4,3,2,2]
解释: 输入数组表示数字 4321。
'''


class Solution:
    def plusOne(self, digits: List[int]) -> List[int]:
        str1 = ''
        for each in digits:
            str1 = str1 + str(each)
        str2 = str(int(str1) + 1)
        return [int(e) for e in str2]

# coding:utf-8
'''
1433. 检查一个字符串是否可以打破另一个字符串
给你两个字符串 s1 和 s2 ,它们长度相等,请你检查是否存在一个 s1  的排列可以打破 s2 的一个排列,或者是否存在一个 s2 的排列可以打破 s1 的一个排列。
字符串 x 可以打破字符串 y (两者长度都为 n )需满足对于所有 i(在 0 到 n - 1 之间)都有 x[i] >= y[i](字典序意义下的顺序)。
示例 1:
输入:s1 = "abc", s2 = "xya"
输出:true
解释:"ayx" 是 s2="xya" 的一个排列,"abc" 是字符串 s1="abc" 的一个排列,且 "ayx" 可以打破 "abc" 。
示例 2:
输入:s1 = "abe", s2 = "acd"
输出:false
解释:s1="abe" 的所有排列包括:"abe","aeb","bae","bea","eab" 和 "eba" ,s2="acd" 的所有排列包括:"acd","adc","cad","cda","dac" 和 "dca"。然而没有任何 s1 的排列可以打破 s2 的排列。也没有 s2 的排列能打破 s1 的排列。
示例 3:
输入:s1 = "leetcodee", s2 = "interview"
输出:true
'''
class Solution:
    def checkIfCanBreak(self, s1: str, s2: str) -> bool:
        s1_list, s2_list = sorted(list(s1)), sorted(list(s2))
        s1_count, s2_count, same = 0, 0, 0
        for i in range(len(s1_list)):
            a, b = s1_list[i], s2_list[i]
            if a > b:
                s1_count += 1
            elif a < b:
                s2_count += 1
            else:
                same += 1
        if s1_count == 0 or s2_count == 0:
            return True
        else:
            return False

# coding:utf-8
'''
657. 机器人能否返回原点
在二维平面上,有一个机器人从原点 (0, 0) 开始。给出它的移动顺序,判断这个机器人在完成移动后是否在 (0, 0) 处结束。
移动顺序由字符串表示。字符 move[i] 表示其第 i 次移动。机器人的有效动作有 R(右),L(左),U(上)和 D(下)。如果机器人在完成所有动作后返回原点,则返回 true。否则,返回 false。
注意:机器人“面朝”的方向无关紧要。 “R” 将始终使机器人向右移动一次,“L” 将始终向左移动等。此外,假设每次移动机器人的移动幅度相同。

示例 1:

输入: "UD"
输出: true
解释:机器人向上移动一次,然后向下移动一次。所有动作都具有相同的幅度,因此它最终回到它开始的原点。因此,我们返回 true。
示例 2:

输入: "LL"
输出: false
解释:机器人向左移动两次。它最终位于原点的左侧,距原点有两次 “移动” 的距离。我们返回 false,因为它在移动结束时没有返回原点。
'''

class Solution:
    def judgeCircle(self, moves: str) -> bool:
        list1 = [0, 0]
        for each in moves:
            if each == 'R':
                list1[0] += 1
            elif each == 'L':
                list1[0] = list1[0]-1
            elif each == 'U':
                list1[1] += 1
            else:
                list1[1] = list1[1]-1
        if list1[0] == 0 and list1[1] == 0:
            return True
        else:
            return False

# coding:utf-8
'''
38. 外观数列
「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。前五项如下:
1.     1
2.     11
3.     21
4.     1211
5.     111221
1 被读作  "one 1"  ("一个一") , 即 11。
11 被读作 "two 1s" ("两个一"), 即 21。
21 被读作 "one 2",  "one 1" ("一个二" ,  "一个一") , 即 1211。
给定一个正整数 n(1 ≤ n ≤ 30),输出外观数列的第 n 项。
注意:整数序列中的每一项将表示为一个字符串。
示例 1:
输入: 1
输出: "1"
解释:这是一个基本样例。
示例 2:
输入: 4
输出: "1211"
解释:当 n = 3 时,序列是 "21",其中我们有 "2" 和 "1" 两组,"2" 可以读作 "12",也就是出现频次 = 1 而 值 = 2;类似 "1" 可以读作 "11"。所以答案是 "12" 和 "11" 组合在一起,也就是 "1211"。
'''

class Solution:
    def countAndSay(self, n: int) -> str:
        pre = ''
        res = ''
        for i in range(n):
            if i == 0:
                pre = '1'
                res = '1'
                continue
            if i == 1:
                pre = '11'
                res = '11'
                continue
            count = 1
            res = ''
            num = pre[0]
            for j in range(1, len(pre), 1):
                if pre[j] == num:
                    count += 1
                else:
                    res = res + str(count) + num
                    num = pre[j]
                    count = 1
            res = res + str(count) + num
            pre = res
        return res
'''
67. 二进制求和
给你两个二进制字符串,返回它们的和(用二进制表示)。
输入为 非空 字符串且只包含数字 1 和 0。
示例 1:
输入: a = "11", b = "1"
输出: "100"
示例 2:
输入: a = "1010", b = "1011"
输出: "10101"
'''
class Solution:
    def addBinary(self, a: str, b: str) -> str:
        num = int(a, 2) + int(b, 2)
        ans = bin(num)
        return ans[2:]

# coding:utf-8
'''
572. 另一个树的子树
给定两个非空二叉树 s 和 t,检验 s 中是否包含和 t 具有相同结构和节点值的子树。s 的一个子树包括 s 的一个节点和这个节点的所有子孙。s 也可以看做它自身的一棵子树。

示例 1:
给定的树 s:

     3
    / \
   4   5
  / \
 1   2
给定的树 t:

   4
  / \
 1   2
返回 true,因为 t 与 s 的一个子树拥有相同的结构和节点值。

示例 2:
给定的树 s:

     3
    / \
   4   5
  / \
 1   2
    /
   0
给定的树 t:

   4
  / \
 1   2
返回 false。
'''
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def isSubtree(self, s: TreeNode, t: TreeNode) -> bool:
        s_1 = "".join(self.postorder(s))
        t_1 = "".join(self.postorder(t))
        print(s_1)
        print(t_1)
        if t_1.find(s_1) != -1:
            return True
        else:
            return False
    def postorder(self, root, ans=[]):
        if root.left and root.left !='null':
            self.postorder(root.left, ans)
        if root.right and root.right !='null':
            self.postorder(root.right, ans)
        ans.append(str(root.val))
        return ans

# 别人的解法
class Solution:
    def isSubtree(self, s: TreeNode, t: TreeNode) -> bool:
        return str(s).find(str(t)) != -1

# coding:utf-8
'''
面试题58 - II. 左旋转字符串
字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。
示例 1:
输入: s = "abcdefg", k = 2
输出: "cdefgab"
示例 2:

输入: s = "lrloseumgh", k = 6
输出: "umghlrlose"
'''

class Solution:
    def reverseLeftWords(self, s: str, n: int) -> str:
        return s[n:] + s[:n]
# coding:utf-8
'''
1221. 分割平衡字符串
在一个「平衡字符串」中,'L' 和 'R' 字符的数量是相同的。
给出一个平衡字符串 s,请你将它分割成尽可能多的平衡字符串。
返回可以通过分割得到的平衡字符串的最大数量。
示例 1:
输入:s = "RLRRLLRLRL"
输出:4
解释:s 可以分割为 "RL", "RRLL", "RL", "RL", 每个子字符串中都包含相同数量的 'L' 和 'R'。
示例 2:

输入:s = "RLLLLRRRLR"
输出:3
解释:s 可以分割为 "RL", "LLLRRR", "LR", 每个子字符串中都包含相同数量的 'L' 和 'R'。
示例 3:

输入:s = "LLLLRRRR"
输出:1
解释:s 只能保持原样 "LLLLRRRR".
'''


class Solution:
    def balancedStringSplit(self, s: str) -> int:
        r_count = 0
        l_count = 0
        all_count = 0
        for each in s:
            if each == 'R':
                r_count += 1
            elif each == 'L':
                l_count += 1
            if r_count == l_count:
                all_count += 1
                r_count = 0
                l_count = 0
        return all_count


# coding:utf-8
'''
804. 唯一摩尔斯密码词
难度
简单
114
国际摩尔斯密码定义一种标准编码方式,将每个字母对应于一个由一系列点和短线组成的字符串, 比如: "a" 对应 ".-", "b" 对应 "-...", "c" 对应 "-.-.", 等等。

为了方便,所有26个英文字母对应摩尔斯密码表如下:

[".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."]
给定一个单词列表,每个单词可以写成每个字母对应摩尔斯密码的组合。例如,"cab" 可以写成 "-.-..--...",(即 "-.-." + "-..." + ".-"字符串的结合)。我们将这样一个连接过程称作单词翻译。

返回我们可以获得所有词不同单词翻译的数量。

例如:
输入: words = ["gin", "zen", "gig", "msg"]
输出: 2
解释:
各单词翻译如下:
"gin" -> "--...-."
"zen" -> "--...-."
"gig" -> "--...--."
"msg" -> "--...--."

共有 2 种不同翻译, "--...-." 和 "--...--.".
'''

import collections

class Solution:
    def uniqueMorseRepresentations(self, words: List[str]) -> int:
        dict1 = collections.OrderedDict()
        list1 = [chr(i) for i in range(97, 123)]
        list2 = [".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---",".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--.."]
        for i in range(len(list1)):
            dict1[list1[i]] = list2[i]
        res = []
        for each in words:
            str1 = ''
            for e in each:
                str1 = str1 + dict1[e]
            res.append(str1)
        return len(list(set(res)))

# coding:utf-8
'''
551. 学生出勤记录 I
给定一个字符串来代表一个学生的出勤记录,这个记录仅包含以下三个字符:

'A' : Absent,缺勤
'L' : Late,迟到
'P' : Present,到场
如果一个学生的出勤记录中不超过一个'A'(缺勤)并且不超过两个连续的'L'(迟到),那么这个学生会被奖赏。

你需要根据这个学生的出勤记录判断他是否会被奖赏。

示例 1:

输入: "PPALLP"
输出: True
示例 2:

输入: "PPALLL"
输出: False

'''


class Solution:
    def checkRecord(self, s: str) -> bool:
        if s.count('A') > 1:
            return False
        if s.find('LLL') != -1:
            return False
        else:
            return True
# coding:utf-8
'''
50. Pow(x, n)
实现 pow(x, n) ,即计算 x 的 n 次幂函数。
示例 1:

输入: 2.00000, 10
输出: 1024.00000
示例 2:

输入: 2.10000, 3
输出: 9.26100
示例 3:

输入: 2.00000, -2
输出: 0.25000
解释: 2-2 = 1/22 = 1/4 = 0.25

'''
class Solution:
    def fenzhi_pow(self, x1, n1):
        if n1 == 1:
            return x1
        if n1 % 2 == 0:
            half = self.fenzhi_pow(x1, n1 // 2)
            return half * half
        else:
            half = self.fenzhi_pow(x1, n1 // 2)
            return half * half * x1
    def myPow(self, x: float, n: int) -> float:
        if n == 0:
            return 1.0
        if n < 0:
            n = -n
            x = 1 / x
        return self.fenzhi_pow(x, n)

# coding:utf-8
'''
1394. 找出数组中的幸运数
在整数数组中,如果一个整数的出现频次和它的数值大小相等,我们就称这个整数为「幸运数」。

给你一个整数数组 arr,请你从中找出并返回一个幸运数。

如果数组中存在多个幸运数,只需返回 最大 的那个。
如果数组中不含幸运数,则返回 -1 。


示例 1:

输入:arr = [2,2,3,4]
输出:2
解释:数组中唯一的幸运数是 2 ,因为数值 2 的出现频次也是 2 。
示例 2:

输入:arr = [1,2,2,3,3,3]
输出:3
解释:1、2 以及 3 都是幸运数,只需要返回其中最大的 3 。
示例 3:

输入:arr = [2,2,2,3,3]
输出:-1
解释:数组中不存在幸运数。
示例 4:

输入:arr = [5]
输出:-1
示例 5:

输入:arr = [7,7,7,7,7,7,7]
输出:7

'''
class Solution:
    def findLucky(self, arr: List[int]) -> int:
        dict1 = {}
        for each in arr:
            if str(each) not in dict1:
                dict1[str(each)] = 1
            else:
                dict1[str(each)] += 1
        res = []
        for key in dict1:
            if int(key) == dict1[key]:
                res.append(int(key))
        if not res:
            return -1
        return sorted(res)[-1]

# coding:utf-8
'''
136. 只出现一次的数字
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

说明:

你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

示例 1:

输入: [2,2,1]
输出: 1
示例 2:

输入: [4,1,2,1,2]
输出: 4
'''
class Solution(object):
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        nums.sort()
        for i in range(0, len(nums) - 1, 2):
            if nums[i] != nums[i + 1]:
                return nums[i]
        return nums[-1]

# coding:utf-8
'''
917. 仅仅反转字母
给定一个字符串 S,返回 “反转后的” 字符串,其中不是字母的字符都保留在原地,而所有字母的位置发生反转。
示例 1:

输入:"ab-cd"
输出:"dc-ba"
示例 2:

输入:"a-bC-dEf-ghIj"
输出:"j-Ih-gfE-dCba"
示例 3:

输入:"Test1ng-Leet=code-Q!"
输出:"Qedo1ct-eeLg=ntse-T!"
'''
import re

class Solution:
    def reverseOnlyLetters(self, S: str) -> str:
        result = ''.join(re.findall(r'[A-Za-z]', S))
        list1 = []
        for each in S:
            if each.isalpha():
                list1.append('')
            else:
                list1.append(each)
        tag = 0
        for i in range(len(list1)):
            e = list1[i]
            if not e:
                tag += 1
                list1[i] = result[-tag]
        return ''.join(list1)

# coding:utf-8
'''
1436. 旅行终点站
给你一份旅游线路图,该线路图中的旅行线路用数组 paths 表示,其中 paths[i] = [cityAi, cityBi] 表示该线路将会从 cityAi 直接前往 cityBi 。请你找出这次旅行的终点站,即没有任何可以通往其他城市的线路的城市。
题目数据保证线路图会形成一条不存在循环的线路,因此只会有一个旅行终点站。

示例 1:
输入:paths = [["London","New York"],["New York","Lima"],["Lima","Sao Paulo"]]
输出:"Sao Paulo"
解释:从 "London" 出发,最后抵达终点站 "Sao Paulo" 。本次旅行的路线是 "London" -> "New York" -> "Lima" -> "Sao Paulo" 。
示例 2:

输入:paths = [["B","C"],["D","B"],["C","A"]]
输出:"A"
解释:所有可能的线路是:
"D" -> "B" -> "C" -> "A".
"B" -> "C" -> "A".
"C" -> "A".
"A".
显然,旅行终点站是 "A" 。
示例 3:

输入:paths = [["A","Z"]]
输出:"Z"
'''


class Solution:
    def destCity(self, paths: List[List[str]]) -> str:
        dict1 = {}
        for each in paths:
            for e in each:
                if e not in dict1:
                    dict1[e] = 1
                else:
                    dict1[e] += 1
        list1 = []
        for key in dict1:
            if dict1[key] == 1:
                list1.append(key)
        for each in paths:
            if each[-1] in list1:
                return each[-1]

'''
1455. 检查单词是否为句中其他单词的前缀
给你一个字符串 sentence 作为句子并指定检索词为 searchWord ,其中句子由若干用 单个空格 分隔的单词组成。

请你检查检索词 searchWord 是否为句子 sentence 中任意单词的前缀。

如果 searchWord 是某一个单词的前缀,则返回句子 sentence 中该单词所对应的下标(下标从 1 开始)。
如果 searchWord 是多个单词的前缀,则返回匹配的第一个单词的下标(最小下标)。
如果 searchWord 不是任何单词的前缀,则返回 -1 。
字符串 S 的 「前缀」是 S 的任何前导连续子字符串。
示例 1:

输入:sentence = "i love eating burger", searchWord = "burg"
输出:4
解释:"burg" 是 "burger" 的前缀,而 "burger" 是句子中第 4 个单词。
示例 2:

输入:sentence = "this problem is an easy problem", searchWord = "pro"
输出:2
解释:"pro" 是 "problem" 的前缀,而 "problem" 是句子中第 2 个也是第 6 个单词,但是应该返回最小下标 2 。
示例 3:

输入:sentence = "i am tired", searchWord = "you"
输出:-1
解释:"you" 不是句子中任何单词的前缀。
示例 4:

输入:sentence = "i use triple pillow", searchWord = "pill"
输出:4
示例 5:

输入:sentence = "hello from the other side", searchWord = "they"
输出:-1
'''


class Solution:
    def isPrefixOfWord(self, sentence: str, searchWord: str) -> int:
        list1 = sentence.split()
        for each in list1:
            if each.startswith(searchWord):
                return list1.index(each) + 1
        return -1


'''
面试题67. 把字符串转换成整数
写一个函数 StrToInt,实现把字符串转换成整数这个功能。不能使用 atoi 或者其他类似的库函数。

首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。

当我们寻找到的第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字组合起来,作为该整数的正负号;假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成整数。

该字符串除了有效的整数部分之后也可能会存在多余的字符,这些字符可以被忽略,它们对于函数不应该造成影响。

注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换。

在任何情况下,若函数不能进行有效的转换时,请返回 0。

说明:

假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−231,  231 − 1]。如果数值超过这个范围,请返回  INT_MAX (231 − 1) 或 INT_MIN (−231) 。

示例 1:

输入: "42"
输出: 42
示例 2:

输入: "   -42"
输出: -42
解释: 第一个非空白字符为 '-', 它是一个负号。
     我们尽可能将负号与后面所有连续出现的数字组合起来,最后得到 -42 。
示例 3:

输入: "4193 with words"
输出: 4193
解释: 转换截止于数字 '3' ,因为它的下一个字符不为数字。
示例 4:

输入: "words and 987"
输出: 0
解释: 第一个非空字符是 'w', 但它不是数字或正、负号。
     因此无法执行有效的转换。
示例 5:

输入: "-91283472332"
输出: -2147483648
解释: 数字 "-91283472332" 超过 32 位有符号整数范围。
     因此返回 INT_MIN (−231) 。
'''


class Solution:
    def strToInt(self, str: str) -> int:
        if not str:
            return 0
        import re
        return max(-(1 << 31), min((1 << 31) - 1, int(*re.findall('^\s*[+-]?\d+', str))))


'''
1163. 按字典序排在最后的子串
给你一个字符串 s,找出它的所有子串并按字典序排列,返回排在最后的那个子串。

示例 1:

输入:"abab"
输出:"bab"
解释:我们可以找出 7 个子串 ["a", "ab", "aba", "abab", "b", "ba", "bab"]。按字典序排在最后的子串是 "bab"。
示例 2:

输入:"leetcode"
输出:"tcode"
'''


class Solution:
    def lastSubstring(self, s: str) -> str:
        return max(s[i:] for i in range(len(s)))


def lastSubstring(s: str) -> str:
    list1 = []
    for i in range(len(s)):
        list1.append(s[i:])
    print(list1)
    print(max(list1))
    return max(s[i:] for i in range(len(s)))


lastSubstring('abab')

'''
1202. 交换字符串中的元素
给你一个字符串 s,以及该字符串中的一些「索引对」数组 pairs,其中 pairs[i] = [a, b] 表示字符串中的两个索引(编号从 0 开始)。

你可以 任意多次交换 在 pairs 中任意一对索引处的字符。

返回在经过若干次交换后,s 可以变成的按字典序最小的字符串。

示例 1:

输入:s = "dcab", pairs = [[0,3],[1,2]]
输出:"bacd"
解释:
交换 s[0] 和 s[3], s = "bcad"
交换 s[1] 和 s[2], s = "bacd"
示例 2:

输入:s = "dcab", pairs = [[0,3],[1,2],[0,2]]
输出:"abcd"
解释:
交换 s[0] 和 s[3], s = "bcad"
交换 s[0] 和 s[2], s = "acbd"
交换 s[1] 和 s[2], s = "abcd"
示例 3:

输入:s = "cba", pairs = [[0,1],[1,2]]
输出:"abc"
解释:
交换 s[0] 和 s[1], s = "bca"
交换 s[1] 和 s[2], s = "bac"
交换 s[0] 和 s[1], s = "abc"
'''


def smallestStringWithSwaps(s, pairs):
    s = list(s)
    for each in pairs:
        s[each[0]], s[each[1]] = s[each[1]], s[each[0]]
    return ''.join(s)

s = "dcab"
pairs = [[0,3],[1,2],[0,2]]
print(smallestStringWithSwaps(s, pairs))

# coding:utf-8
'''
1071. 字符串的最大公因子
对于字符串 S 和 T,只有在 S = T + ... + T(T 与自身连接 1 次或多次)时,我们才认定 “T 能除尽 S”。

返回最长字符串 X,要求满足 X 能除尽 str1 且 X 能除尽 str2。


示例 1:

输入:str1 = "ABCABC", str2 = "ABC"
输出:"ABC"
示例 2:

输入:str1 = "ABABAB", str2 = "ABAB"
输出:"AB"
示例 3:

输入:str1 = "LEET", str2 = "CODE"
输出:""
'''

import math
class Solution:
    def gcdOfStrings(self, str1: str, str2: str) -> str:
        candidate_len = math.gcd(len(str1), len(str2))
        candidate = str1[: candidate_len]
        if str1 + str2 == str2 + str1:
            return candidate
        return ''

# coding:utf-8
'''
744. 寻找比目标字母大的最小字母
给你一个排序后的字符列表 letters ,列表中只包含小写英文字母。另给出一个目标字母 target,请你寻找在这一有序列表里比目标字母大的最小字母。

在比较时,字母是依序循环出现的。举个例子:

如果目标字母 target = 'z' 并且字符列表为 letters = ['a', 'b'],则答案返回 'a'


示例:

输入:
letters = ["c", "f", "j"]
target = "a"
输出: "c"

输入:
letters = ["c", "f", "j"]
target = "c"
输出: "f"

输入:
letters = ["c", "f", "j"]
target = "d"
输出: "f"

输入:
letters = ["c", "f", "j"]
target = "g"
输出: "j"

输入:
letters = ["c", "f", "j"]
target = "j"
输出: "c"

输入:
letters = ["c", "f", "j"]
target = "k"
输出: "c"
'''

class Solution:
    def nextGreatestLetter(self, letters: List[str], target: str) -> str:
        list1 = [ord(each) for each in letters]
        for each in list1:
            if each > ord(target):
                return chr(each)
        return letters[0]

# coding:utf-8
'''
1446. 连续字符
给你一个字符串 s ,字符串的「能量」定义为:只包含一种字符的最长非空子字符串的长度。

请你返回字符串的能量。

示例 1:

输入:s = "leetcode"
输出:2
解释:子字符串 "ee" 长度为 2 ,只包含字符 'e' 。
示例 2:

输入:s = "abbcccddddeeeeedcba"
输出:5
解释:子字符串 "eeeee" 长度为 5 ,只包含字符 'e' 。
示例 3:

输入:s = "triplepillooooow"
输出:5
示例 4:

输入:s = "hooraaaaaaaaaaay"
输出:11
示例 5:

输入:s = "tourist"
输出:1

'''


def maxPower(s):
    if not s:
        return 0
    if len(s) == 1:
        return 1
    list1 = []
    j = 0
    tag = 0
    for i in range(len(s)):
        # print(s[j], s[i],list1)
        if s[i] == s[j]:
            tag += 1
        else:
            list1.append(tag)
            tag = 1
            j = i
        if i == len(s)-1 and s[i]==s[j]:
            list1.append(tag)

    return max(list1)

s = 'ccc'
print(maxPower(s))

# coding:utf-8
'''
443. 压缩字符串
给定一组字符,使用原地算法将其压缩。
压缩后的长度必须始终小于或等于原数组长度。
数组的每个元素应该是长度为1 的字符(不是 int 整数类型)。
在完成原地修改输入数组后,返回数组的新长度。
进阶:
你能否仅使用O(1) 空间解决问题?
示例 1:
输入:
["a","a","b","b","c","c","c"]
输出:
返回6,输入数组的前6个字符应该是:["a","2","b","2","c","3"]
说明:
"aa"被"a2"替代。"bb"被"b2"替代。"ccc"被"c3"替代。
示例 2:
输入:
["a"]
输出:
返回1,输入数组的前1个字符应该是:["a"]
说明:
没有任何字符串被替代。
示例 3:
输入:
["a","b","b","b","b","b","b","b","b","b","b","b","b"]
输出:
返回4,输入数组的前4个字符应该是:["a","b","1","2"]。
说明:
由于字符"a"不重复,所以不会被压缩。"bbbbbbbbbbbb"被“b12”替代。
注意每个数字在数组中都有它自己的位置。
'''


def compress(chars) -> int:
    if not chars:
        return []
    if len(chars) == 1:
        return chars
    list1 = []
    j = 0
    tag = 0
    for i in range(len(chars)):
        if chars[i] == chars[j]:
            tag += 1
        else:
            if tag == 1:
                list1.append(chars[i - 1])
            else:
                list1.append(chars[i - 1] + str(tag))
            tag = 1
            j = i
        if i == len(chars) - 1 and chars[i] == chars[j]:
            if tag == 1:
                list1.append(chars[i - 1])
            else:
                list1.append(chars[i - 1] + str(tag))
    return len(list(''.join(list1)))

class Solution(object):
    def compress(self, chars):
        anchor = write = 0
        for read, c in enumerate(chars):
            if read + 1 == len(chars) or chars[read + 1] != c:
                chars[write] = chars[anchor]
                write += 1
                if read > anchor:
                    for digit in str(read - anchor + 1):
                        chars[write] = digit
                        write += 1
                anchor = read + 1
        return write

# coding:utf-8
'''
599. 两个列表的最小索引总和
假设Andy和Doris想在晚餐时选择一家餐厅,并且他们都有一个表示最喜爱餐厅的列表,每个餐厅的名字用字符串表示。
你需要帮助他们用最少的索引和找出他们共同喜爱的餐厅。 如果答案不止一个,则输出所有答案并且不考虑顺序。 你可以假设总是存在一个答案。
示例 1:
输入:
["Shogun", "Tapioca Express", "Burger King", "KFC"]
["Piatti", "The Grill at Torrey Pines", "Hungry Hunter Steakhouse", "Shogun"]
输出: ["Shogun"]
解释: 他们唯一共同喜爱的餐厅是“Shogun”。
示例 2:

输入:
["Shogun", "Tapioca Express", "Burger King", "KFC"]
["KFC", "Shogun", "Burger King"]
输出: ["Shogun"]
解释: 他们共同喜爱且具有最小索引和的餐厅是“Shogun”,它有最小的索引和1(0+1)。
'''
class Solution:
    def findRestaurant(self, list1: List[str], list2: List[str]) -> List[str]:
        dict1 = {}
        for i in range(len(list1)):
            for j in range(len(list2)):
                if list1[i] == list2[j]:
                    dict1[list1[i]] = i+j
        list3 = []
        for key in dict1:
            list3.append(dict1[key])
        max_ = min(list3)
        res = []
        for key in dict1:
            if dict1[key] == max_:
                res.append(key)
        return res
 

62、

'''
237. 删除链表中的节点
请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点,你将只被给定要求被删除的节点。

现有一个链表 -- head = [4,5,1,9],它可以表示为:
4 --->5--->1--->9
示例 1:

输入: head = [4,5,1,9], node = 5
输出: [4,1,9]
解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.
示例 2:

输入: head = [4,5,1,9], node = 1
输出: [4,5,9]
解释: 给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9.


说明:

链表至少包含两个节点。
链表中所有节点的值都是唯一的。
给定的节点为非末尾节点并且一定是链表中的一个有效节点。
不要从你的函数中返回任何结果。
'''
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def deleteNode(self, node):
        """
        :type node: ListNode
        :rtype: void Do not return anything, modify node in-place instead.
        """
        node.val = node.next.val
        node.next = node.next.next

63、

'''
206. 反转链表
反转一个单链表。

示例:

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
进阶:
你可以迭代或递归地反转链表。你能否用两种方法解决这道题?
'''
# Definition for singly-linked list.
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        list1 = []
        while head:
            list1.insert(0, head.val)
            head = head.next
        pre = ListNode(0)
        node_start = pre
        for i in range(len(list1)):
            node_start.val = list1[i]
            if i != len(list1)-1:
                node_start.next = ListNode(0)
            else:
                node_start.next = None

        return pre

class Solution(object):
    def reverseList(self, head):
        pre = None
        curr = head
        while curr:
            temp = curr.next
            curr.next = pre
            pre = curr
            curr = temp
        return pre

64、234. 回文链表

请判断一个链表是否为回文链表。

示例 1:

输入: 1->2
输出: false
示例 2:

输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution:
    def isPalindrome(self, head: ListNode) -> bool:
        list1 = []
        while head:
            list1.append(head.val)
            head = head.next
        str1 = ''.join(list1)
        str2 = ''.join(list1.reverse())
        if str1 == str2:
            return True
        else:
            return False

65、125. 验证回文串

给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。

说明:本题中,我们将空字符串定义为有效的回文串。

示例 1:

输入: "A man, a plan, a canal: Panama"
输出: true
示例 2:

输入: "race a car"
输出: false
def isPalindrome(s):
    str1 = ''
    for each in s:
        if each.isalpha() or each.isdigit():
            str1 = str1 + str(each.lower())
    list1 = list(str1)
    list1.reverse()
    str2 = ''.join(list1)
    if str1 == str2:
        return True
    else:
        return False

66、面试题 02.05. 链表求和

给定两个用链表表示的整数,每个节点包含一个数位。

这些数位是反向存放的,也就是个位排在链表首部。

编写函数对这两个整数求和,并用链表形式返回结果。


示例:

输入:(7 -> 1 -> 6) + (5 -> 9 -> 2),即617 + 295
输出:2 -> 1 -> 9,即912
进阶:假设这些数位是正向存放的,请再做一遍。

示例:

输入:(6 -> 1 -> 7) + (2 -> 9 -> 5),即617 + 295
输出:9 -> 1 -> 2,即912
class Solution:
    def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
        head = ListNode(0)
        node = head
        remaining = 0
        while l1 or l2:
            if l1 == None:
                node.next = l2
                l1 = ListNode(0)
            if l2 == None:
                node.next = l1
                l2 = ListNode(0)
            remaining += l1.val + l2.val
            node.next = ListNode(remaining % 10)
            remaining = remaining // 10
            node = node.next
            l1 = l1.next
            l2 = l2.next
        if remaining:
            node.next = ListNode(remaining)
        return head.next

67、605. 种花问题

假设你有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花卉不能种植在相邻的地块上,它们会争夺水源,两者都会死去。

给定一个花坛(表示为一个数组包含0和1,其中0表示没种植花,1表示种植了花),和一个数 n 。能否在不打破种植规则的情况下种入 n 朵花?能则返回True,不能则返回False。

示例 1:

输入: flowerbed = [1,0,0,0,1], n = 1
输出: True
示例 2:

输入: flowerbed = [1,0,0,0,1], n = 2
输出: False
注意:

数组内已种好的花不会违反种植规则。
输入的数组长度范围为 [1, 20000]。
n 是非负整数,且不会超过输入数组的大小。
class Solution:
    def canPlaceFlowers(self, flowerbed: List[int], n: int) -> bool:
        flowerbed = [0] + flowerbed
        flowerbed = flowerbed + [0]
        for i in range(1, len(flowerbed) - 1):
            if flowerbed[i - 1] == 0 and flowerbed[i] == 0 and flowerbed[i + 1] == 0:
                n = n - 1
                flowerbed[i] = 1
        return n <= 0

68、1431. 拥有最多糖果的孩子

给你一个数组 candies 和一个整数 extraCandies ,其中 candies[i] 代表第 i 个孩子拥有的糖果数目。

对每一个孩子,检查是否存在一种方案,将额外的 extraCandies 个糖果分配给孩子们之后,此孩子有 最多 的糖果。注意,允许有多个孩子同时拥有 最多 的糖果数目。
示例 1:

输入:candies = [2,3,5,1,3], extraCandies = 3
输出:[true,true,true,false,true]
解释:
孩子 1 有 2 个糖果,如果他得到所有额外的糖果(3个),那么他总共有 5 个糖果,他将成为拥有最多糖果的孩子。
孩子 2 有 3 个糖果,如果他得到至少 2 个额外糖果,那么他将成为拥有最多糖果的孩子。
孩子 3 有 5 个糖果,他已经是拥有最多糖果的孩子。
孩子 4 有 1 个糖果,即使他得到所有额外的糖果,他也只有 4 个糖果,无法成为拥有糖果最多的孩子。
孩子 5 有 3 个糖果,如果他得到至少 2 个额外糖果,那么他将成为拥有最多糖果的孩子。
示例 2:

输入:candies = [4,2,1,1,2], extraCandies = 1
输出:[true,false,false,false,false]
解释:只有 1 个额外糖果,所以不管额外糖果给谁,只有孩子 1 可以成为拥有糖果最多的孩子。
示例 3:

输入:candies = [12,1,12], extraCandies = 10
输出:[true,false,true]
class Solution:
    def kidsWithCandies(self, candies: List[int], extraCandies: int) -> List[bool]:
        list1 = []
        max_ = max(candies)
        for each in candies:
            if each + extraCandies >= max_:
                list1.append(True)
            else:
                list1.append(False)
        return list1

69、944. 删列造序

给定由 N 个小写字母字符串组成的数组 A,其中每个字符串长度相等。
你需要选出一组要删掉的列 D,对 A 执行删除操作,使 A 中剩余的每一列都是 非降序 排列的,然后请你返回 D.length 的最小可能值。
删除 操作的定义是:选出一组要删掉的列,删去 A 中对应列中的所有字符,形式上,第 n 列为 [A[0][n], A[1][n], ..., A[A.length-1][n]])。(可以参见 删除操作范例)

示例 1:

输入:["cba", "daf", "ghi"]
输出:1
解释:
当选择 D = {1},删除后 A 的列为:["c","d","g"] 和 ["a","f","i"],均为非降序排列。
若选择 D = {},那么 A 的列 ["b","a","h"] 就不是非降序排列了。
示例 2:

输入:["a", "b"]
输出:0
解释:D = {}
示例 3:

输入:["zyx", "wvu", "tsr"]
输出:3
解释:D = {0, 1, 2}
class Solution:
    def minDeletionSize(self, A: List[str]) -> int:
        list1 = []
        for i in range(len(A[0])):
            linshi = []
            for j in range(len(A)):
                linshi.append(A[j][i])
            list1.append(linshi)
        count = 0
        for each in list1:
            linshi = [x for x in each]
            each.sort()
            if linshi != each:
                count += 1
        return count

70、984. 不含 AAA 或 BBB 的字符串


给定两个整数 A 和 B,返回任意字符串 S,要求满足:

S 的长度为 A + B,且正好包含 A 个 'a' 字母与 B 个 'b' 字母;
子串 'aaa' 没有出现在 S 中;
子串 'bbb' 没有出现在 S 中。


示例 1:

输入:A = 1, B = 2
输出:"abb"
解释:"abb", "bab" 和 "bba" 都是正确答案。
示例 2:

输入:A = 4, B = 1
输出:"aabaa"


class Solution:
    def strWithout3a3b(self, A: int, B: int) -> str:
        if A == B:
            return "ab" * A

        ans = ""
        la = A
        lb = B
        while la > 0 and lb > 0:
            if la > lb:
                ans += "aab"
                la -= 2
                lb -= 1
            elif la < lb:
                ans += "bba"
                la -= 1
                lb -= 2
            else:
                if A > B:
                    ans += "ab" * la
                else:
                    ans += "ba" * la
                la = 0
                lb = 0

        if A > B:
            ans += "a" * la + "b" * lb
        else:
            ans += "b" * lb + "a" * la

        return ans


 

71、 21. 合并两个有序链表

date:2020.4.22

将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 

示例:

输入:1->2->4, 1->3->4

输出:1->1->2->3->4->4

 

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        result_node = ListNode(0)
        node = result_node
        head1 = l1
        head2 = l2
        while (head1 and head2):
            if head1.val < head2.val:
                node.next = head1
                head1 = head1.next
                node = node.next
            else:
                node.next = head2
                head2 = head2.next
                node = node.next
        while head1:
            node.next = head1
            head1 = head1.next
            node = node.next
        while head2:
            node.next = head2
            head2 = head2.next
            node = node.next
        return result_node.next

72、 面试题50. 第一个只出现一次的字符

date:2020.4.21

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。

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

示例 1:

输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]

输出: 2

代码如下所示:

class Solution:
    def majorityElement(self, nums: List[int]) -> int:
        dict1 = {}
        for each in nums:
            if each not in dict1:
                dict1[each] = 1
            else:
                dict1[each] += 1
        length = len(nums)//2
        for each in dict1:
            if dict1[each] > length:
                return each

 

73、 面试题50. 第一个只出现一次的字符

date:2020.4.20

在字符串 s 中找出第一个只出现一次的字符。如果没有,返回一个单空格。

示例:

s = "abaccdeff"

返回 "b"

s = ""

返回 " "

代码如下所示:

class Solution:
    def firstUniqChar(self, s: str) -> str:
        d1 = {}
        for each in s:
            if each not in d1:
                d1[each] = 1
            else:
                d1[each] += 1
        for key in s:
            if d1[key] == 1:
                return key
        return ' '

 

74、 面试题15. 二进制中1的个数

date:2020.4.20

请实现一个函数,输入一个整数,输出该数二进制表示中 1 的个数。例如,把 9 表示成二进制是 1001,有 2 位是 1。因此,如果输入 9,则该函数输出 2。

示例 1:

输入:00000000000000000000000000001011

输出:3

解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。

示例 2:

输入:00000000000000000000000010000000

输出:1

解释:输入的二进制串 00000000000000000000000010000000 中,共有一位为 '1'。

示例 3:

输入:11111111111111111111111111111101

输出:31

解释:输入的二进制串 11111111111111111111111111111101 中,共有 31 位为 '1'。

代码如下所示:

class Solution:
    def hammingWeight(self, n: int) -> int:
        return list(str(bin(n))).count('1')

 

75、 面试题18. 删除链表的节点

date:2020.4.17

给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。

返回删除后的链表的头节点。

注意:此题对比原题有改动

示例 1:

输入: head = [4,5,1,9], val = 5

输出: [4,1,9]

解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.

示例 2:

输入: head = [4,5,1,9], val = 1

输出: [4,5,9]

解释: 给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9.

代码如下:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def deleteNode(self, head: ListNode, val: int) -> ListNode:
        pre = head
        if head.val == val:
            return head.next
        while pre.next:
            if pre.next.val == val:
                pre.next = pre.next.next
            else:
                pre = pre.next
        return head

 

76、 面试题11. 旋转数组的最小数字

date:2020.4.16

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。  

示例 1:

输入:[3,4,5,1,2]

输出:1

示例 2:

输入:[2,2,2,0,1]

输出:0

代码如下所示:

 

# 自己的代码
class Solution:
    def minArray(self, numbers: List[int]) -> int:
        return min(numbers)
# 大神的代码:二分查找
class Solution:
    def minArray(self, numbers: List[int]) -> int:
        if not numbers: return 
        start, end = 0, len(numbers) - 1
        while start < end:
            middle = (start + end) // 2
            if numbers[middle] > numbers[end]: start = middle + 1
            elif numbers[middle] < numbers[end]: end = middle
            # 其实这个end-=1很巧妙,因为相等的时候我们无法判断要往哪个方向缩小
            # 所以索性就缩小numbers的长度。
            else: end -= 1
        return numbers[start]

77、 面试题10- II. 青蛙跳台阶问题

date:2020.4.15

一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。

答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

示例 1:

输入:n = 2

输出:2

示例 2:

输入:n = 7

输出:21

提示:

0 <= n <= 100

代买如下:

class Solution:
    def numWays(self, n: int) -> int:
        a, b = 1, 1
        for _ in range(n):
            a, b = b, a + b
        return a % 1000000007

 

78、 面试题09. 用两个栈实现队列

date:2020.4.15

用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )

示例 1:

输入:

["CQueue","appendTail","deleteHead","deleteHead"]

[[],[3],[],[]]

输出:[null,null,3,-1]

示例 2:

输入:

["CQueue","deleteHead","appendTail","appendTail","deleteHead","deleteHead"]

[[],[],[5],[2],[],[]]

输出:[null,-1,null,null,5,2]

代码如下:

class CQueue:
    def __init__(self):
        self.A, self.B = [],[]
    def appendTail(self, value: int) -> None:
        self.A.append(value)
    def deleteHead(self) -> int:
        if self.B:
            return self.B.pop()
        if not self.A:
            return -1
        while self.A:
            self.B.append(self.A.pop())
        return self.B.pop()
# Your CQueue object will be instantiated and called as such:
# obj = CQueue()
# obj.appendTail(value)
# param_2 = obj.deleteHead()

 

79、 面试题06. 从尾到头打印链表

date:2020.4.14

输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

例如,给出

前序遍历 preorder = [3,9,20,15,7]

中序遍历 inorder = [9,3,15,20,7]

返回如下的二叉树:

3

/ \

9 20

/ \

15 7

代码如下所示:

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
        if not preorder:
            return None
        loc = inorder.index(preorder[0])
        root = TreeNode(preorder[0])
        root.left = self.buildTree(preorder[1:loc+1],inorder[:loc])
        root.right = self.buildTree(preorder[loc+1:],inorder[loc+1:])
        return root

80、 面试题06. 从尾到头打印链表

 

 

 

date:2020.4.13

输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。

示例 1:

输入:head = [1,3,2] 输出:[2,3,1]

代码如下所示:

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def reversePrint(self, head: ListNode) -> List[int]:
        list1 = []
        while head:
            list1.insert(0,head.val)
            head = head.next
        return list1

 

81、 面试题05. 替换空格

date:2020.4.13

请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

示例 1:

输入:s = "We are happy."

输出:"We%20are%20happy."

代码如下所示:

class Solution:
    def replaceSpace(self, s: str) -> str:
        return '%20'.join(s.split(" "))

 

82、 面试题04. 二维数组中的查找

date:2020.4.13

在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

示例:

现有矩阵 matrix 如下:

[

[1, 4, 7, 11, 15],

[2, 5, 8, 12, 19],

[3, 6, 9, 16, 22],

[10, 13, 14, 17, 24],

[18, 21, 23, 26, 30]

]

给定 target = 5,返回 true。

给定 target = 20,返回 false。

代码如下所示:

class Solution:
    def findNumberIn2DArray(self, matrix: List[List[int]], target: int) -> bool:
        for i in range(len(matrix)):
            for j in range(len(matrix[i])):
                if matrix[i][j] == target:
                    return True
        return False

 

83、 面试题10- I. 斐波那契数列

date:2020.4.13

写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项。斐波那契数列的定义如下:

F(0) = 0,   F(1) = 1

F(N) = F(N - 1) + F(N - 2), 其中 N > 1.

斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。

答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

示例 1:

输入:n = 2

输出:1

示例 2:

输入:n = 5

输出:5

代码如下:

# 函数递归调用  会出现时间超时问题
class Solution(object):
    def fib(self, n):
        """
        :type n: int
        :rtype: int
        """
        if n < 2:
            return n
        else:
            return self.fib(n - 1) + self.fib(n - 2)
# 下面的方法不会出现时间超时问题
class Solution(object):
    def fib(self, n):
        a, b = 0, 1
        for _ in range(n):
            a, b = b, a + b
        return a % 1000000007

 

84、 151. 翻转字符串里的单词

date:2020.4.10

给定一个字符串,逐个翻转字符串中的每个单词。

示例 1:

输入: "the sky is blue"

输出: "blue is sky the"

示例 2:

输入: "  hello world!  "

输出: "world! hello"

解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。

示例 3:

输入: "a good   example"

输出: "example good a"

解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。

代码如下:

class Solution(object):
    def reverseWords(self, s):
        """
        :type s: str
        :rtype: str
        """
        list1 = [each for each in s.split() if each != '']
        str1 = ''
        for each in list1:
            if str1 != '':
                str1 = each+' '+str1
            else:
                str1 = each
        return str1

 

85、 13. 机器人的运动范围

地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移动一格(不能移动到方格外),也不能进入行坐标和列坐标的数位之和大于k的格子。例如,当k为18时,机器人能够进入方格 [35, 37] ,因为3+5+3+7=18。但它不能进入方格 [35, 38],因为3+5+3+8=19。请问该机器人能够到达多少个格子?

示例 1:

输入:m = 2, n = 3, k = 1

输出:3

示例 1:

输入:m = 3, n = 1, k = 0

输出:1

提示:

1 <= n,m <= 100

0 <= k <= 20

代码如下所示:

# 深度优先搜索
class Solution(object):
    def movingCount(self, m, n, k):
        """
        :type m: int
        :type n: int
        :type k: int
        :rtype: int
        """
        def dfs(m, n, i, j, k, grid):
            if i < 0 or j < 0 or i == m or j == n or i % 10 + i // 10 + j % 10 + j // 10 > k or grid[i][j] == 1:
                return
            grid[i][j] = 1
            dfs(m, n, i + 1, j, k, grid)
            dfs(m, n, i, j - 1, k, grid)
            dfs(m, n, i, j + 1, k, grid)
            dfs(m, n, i - 1, j, k, grid)

        grid = [[0 for _ in range(n)] for _ in range(m)]
        dfs(m, n, 0, 0, k, grid)
        return sum([sum(i) for i in grid])

 

86、 面试题 01.07. 旋转矩阵

给你一幅由 N × N 矩阵表示的图像,其中每个像素的大小为 4 字节。请你设计一种算法,将图像旋转 90 度。

不占用额外内存空间能否做到?

示例 1:

给定 matrix =

[

[1,2,3],

[4,5,6],

[7,8,9]

],

原地旋转输入矩阵,使其变为:

[

[7,4,1],

[8,5,2],

[9,6,3]

]

示例 2:

给定 matrix =

[

[ 5, 1, 9,11],

[ 2, 4, 8,10],

[13, 3, 6, 7],

[15,14,12,16]

],

原地旋转输入矩阵,使其变为:

[

[15,13, 2, 5],

[14, 3, 4, 1],

[12, 6, 8, 9],

[16, 7,10,11]

]

代码如下:

class Solution(object):
    def rotate(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: None Do not return anything, modify matrix in-place instead.
        """
        list1 = []
        for i in range(len(matrix[0])):
            str1 = []
            for j in range(len(matrix)):
                str1.insert(0,matrix[j][i])
            list1.append(str1)
        for i in range(len(list1)):
            matrix[i] = list1[i]

87、 面试题 02.03. 删除中间节点

实现一种算法,删除单向链表中间的某个节点(除了第一个和最后一个节点,不一定是中间节点),假定你只能访问该节点。

示例:

输入:单向链表a->b->c->d->e->f中的节点c

结果:不返回任何数据,但该链表变为a->b->d->e->f

代码:

 

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution(object):
    def deleteNode(self, node):
        """
        :type node: ListNode
        :rtype: void Do not return anything, modify node in-place instead.
        """
        if node.next:
            node.val = node.next.val
            if node.next.next:
                node.next = node.next.next
            else:
                node.next = None

88、找不同

给定两个字符串 s 和 t,它们只包含小写字母。

字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母。

请找出在 t 中被添加的字母。

示例:

输入:

s = "abcd"

t = "abcde"

输出:

e

解释:

'e' 是那个被添加的字母。

代码:

class Solution:
    def findTheDifference(self, s: str, t: str) -> str:
        s_list = sorted(list(s))
        t_list = sorted(list(t))
        for i in range(len(t_list)):
            if len(s_list) == i:
                return t_list[i]
            elif t_list[i] != s_list[i]:
                return t_list[i]

89、字符串中的第一个唯一字符

给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。

案例:

s = "leetcode"

返回 0.

s = "loveleetcode",

返回 2.

代码:

class Solution:
    def firstUniqChar(self, s: str) -> int:
        import collections
        dicr_1 = collections.OrderedDict()
        for i in range(len(s)):
            if s[i] not in dicr_1:
                dicr_1[s[i]] = 1
            else:
                dicr_1[s[i]] += 1
        for key in dicr_1:
            if dicr_1[key] == 1:
                return s.index(key)
        return -1

 

90、缺失数字

给定一个包含 0, 1, 2, ..., n 中 n 个数的序列,找出 0 .. n 中没有出现在序列中的那个数。

示例 1:

输入: [3,0,1]

输出: 2

示例 2:

输入: [9,6,4,2,3,5,7,0,1]

输出: 8

代码:

class Solution:
    def missingNumber(self, nums: List[int]) -> int:
        nums = sorted(nums)
        for i in range(len(nums)):
            if i != nums[i]:
                return i
        return len(nums)

91、丑数

编写一个程序判断给定的数是否为丑数。

丑数就是只包含质因数 2, 3, 5 的正整数。

示例 1:

输入: 6

输出: true

解释: 6 = 2 × 3

示例 2:

输入: 8

输出: true

解释: 8 = 2 × 2 × 2

示例 3:

输入: 14

输出: false

解释: 14 不是丑数,因为它包含了另外一个质因数 7。

说明:

1 是丑数。

输入不会超过 32 位有符号整数的范围: [−231,  231 − 1]。

代码:

class Solution:
    def isUgly(self, num: int) -> bool:
        if num == 1:
            return True
        if num <= 0:
            return False
        while num != 1:
            if num %2 == 0:
                num = num//2
            elif num%3 == 0:
                num = num//3
            elif num%5==0:
                num = num//5
            else:
                return False
        return True
            

92、有效的字母异位词

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。

示例 1:

输入: s = "anagram", t = "nagaram"

输出: true

示例 2:

输入: s = "rat", t = "car"

输出: false

说明:

你可以假设字符串只包含小写字母。

进阶:

如果输入字符串包含 unicode 字符怎么办?你能否调整你的解法来应对这种情况?

解题思路:

字母异位词是指由相同的字母按照不同的顺序组成的单词,根据此含义,那么这两个单词的长度也一定相等,所以我们就可以先将两个单词按照字母的大小进行排序,然后比较两个单词对应位置上的字母是否相等

class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        s_list = sorted(list(s))
        t_list = sorted(list(t))
        if s_list == t_list:
            return True
        else:
            return False

93、2的幂

给定一个整数,编写一个函数来判断它是否是 2 的幂次方。

示例 1:

输入: 1

输出: true

解释: 20 = 1

示例 2:

输入: 16

输出: true

解释: 24 = 16

示例 3:

输入: 218

输出: false

 

class Solution:
    def isPowerOfTwo(self, n: int) -> bool:
        if n <= 0:
            return False
        if n == 1:
            return True
        elif str(n)[-1] not in ['2','4','6','8']:
            return False
        else:
            while n > 1:
                if n%2 == 0:
                    n //=2
                else:
                    return False
            return True

94、计数质数

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

示例:

输入: 10 输出: 4 解释: 小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。

# 代码:
class Solution:
    def countPrimes(self, n: int) -> int:
        if n == 1 or n == 0 or n== 2:
            return 0
        list1 = list(range(1,n))
        list1[0] = 0
        for i in range(2,n):
            if list1[i-1] != 0:
                for j in range(i*2,n,i):
                    list1[j-1] = 0
        return len(list1)-list1.count(0)
# 思路:
# 厄拉多赛筛法

95、打家劫舍

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

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

示例 1:

输入: [1,2,3,1]

输出: 4

解释: 偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。

  偷窃到的最高金额 = 1 + 3 = 4 。

示例 2:

输入: [2,7,9,3,1]

输出: 12

解释: 偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。

  偷窃到的最高金额 = 2 + 9 + 1 = 12 。

 

# 代码:
class Solution:
    def rob(self, nums: List[int]) -> int:
        n1,n2 = 0,0
        for each in nums:
            n2,n1 = max(n1+each,n2),n2
        return n2

# 解题思路:
# 这是一个动态规划问题

96、错误的集合

集合 S 包含从1到 n 的整数。不幸的是,因为数据错误,导致集合里面某一个元素复制了成了集合里面的另外一个元素的值,导致集合丢失了一个整数并且有一个元素重复。

给定一个数组 nums 代表了集合 S 发生错误后的结果。你的任务是首先寻找到重复出现的整数,再找到丢失的整数,将它们以数组的形式返回。

示例 1:

输入: nums = [1,2,2,4]

输出: [2,3]

注意:

给定数组的长度范围是 [2, 10000]。

给定的数组是无序的。

class Solution:
    def findErrorNums(self, nums: List[int]) -> List[int]:
        cuowu = sum(nums)-sum(set(nums))
        linshi = range(1,len(nums)+1)
        zhengque = sum(linshi)-sum(set(nums))
        return [cuowu,zhengque]

97、旋转数组

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

示例 1:

输入: [1,2,3,4,5,6,7] 和 k = 3

输出: [5,6,7,1,2,3,4]

解释:

向右旋转 1 步: [7,1,2,3,4,5,6]

向右旋转 2 步: [6,7,1,2,3,4,5]

向右旋转 3 步: [5,6,7,1,2,3,4]

示例 2:

输入: [-1,-100,3,99] 和 k = 2

输出: [3,99,-1,-100]

解释:

向右旋转 1 步: [99,-1,-100,3]

向右旋转 2 步: [3,99,-1,-100]

说明:

尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。

要求使用空间复杂度为 O(1) 的 原地 算法。

class Solution:
    def rotate(self, nums: List[int], k: int) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        for i in range(k):
            x = nums.pop()
            nums.insert(0,x)

98、排列硬币

你总共有 n 枚硬币,你需要将它们摆成一个阶梯形状,第 k 行就必须正好有 k 枚硬币。

给定一个数字 n,找出可形成完整阶梯行的总行数。

n 是一个非负整数,并且在32位有符号整型的范围内。

示例 1:

n = 5

硬币可排列成以下几行:

¤

¤ ¤

¤ ¤

因为第三行不完整,所以返回2.

示例 2:

n = 8

硬币可排列成以下几行:

¤

¤ ¤

¤ ¤ ¤

¤ ¤

因为第四行不完整,所以返回3.

from math import sqrt, floor
class Solution:
    def arrangeCoins(self, n: int) -> int:
        return floor(sqrt(1/4+2*n)-1/2)

99、快乐数

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

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

示例: 

输入: 19
输出: true
解释: 
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1

class Solution:
    def isHappy(self, n: int) -> bool:
        list1 = []
        while n!= 1:
            n = sum([int(i)**2 for i in str(n)])
            if n not in list1:
                list1.append(n)
            else:
                return False
        return True

100、同构字符串

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

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

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

示例 1:

输入: s = "egg", t = "add"
输出: true
示例 2:

输入: s = "foo", t = "bar"
输出: false
示例 3:

输入: s = "paper", t = "title"
输出: true
说明:
你可以假设 s 和 t 具有相同的长度。

class Solution:
    def isIsomorphic(self, s: str, t: str) -> bool:
        dict1 = {}
        list1 = []
        for i in range(len(t)):
            if s[i] not in dict1:
                if t[i]not in list1:
                    dict1[s[i]] = t[i]
                    list1.append(t[i])
                else:
                    return False
            else:
                if dict1[s[i]] != t[i]:
                    return False
        return True

不断在更新,希望也喜欢算法的你一起努力

你可能感兴趣的:(python)