Leetcode简单题81~100

81.思路:直述题意
# 我们称一个数 X 为好数, 如果它的每位数字逐个地被旋转 180 度后,我们仍可以得到一个有效的,且和 X 不同的数。要求每位数字都要被旋转。
# 如果一个数的每位数字被旋转以后仍然还是一个数字, 则这个数是有效的。0, 1, 和 8 被旋转后仍然是它们自己;2 和 5 可以互相旋转成对方;6 和 9 同理,除了这些以外其他的数字旋转以后都不再是有效的数字。
# 现在我们有一个正整数 N, 计算从 1 到 N 中有多少个数 X 是好数?
# 示例:
# 输入: 10
# 输出: 4
# 解释:
# 在[1, 10]中有四个好数: 2, 5, 6, 9。
# 注意 1 和 10 不是好数, 因为他们在旋转之后不变。
#me
class Solution(object):
def rotatedDigits(self, N):
allnum = {0, 1, 8, 2, 5, 6, 9}
k = 0
for n in range(N+1):
n_nums = set([int(i) for i in str(n)])
if n_nums.issubset(allnum) and not n_nums.issubset({0,1,8}):
k+=1
return k

82.思路:list.insert,list.pop方法
# 给你一个长度固定的整数数组 arr,请你将该数组中出现的每个零都复写一遍,并将其余的元素向右平移。
# 注意:请不要在超过该数组长度的位置写入元素。
# 要求:请对输入的数组就地进行上述修改,不要从函数返回任何东西。
# 示例 1:
# 输入:[1,0,2,3,0,4,5,0]
# 输出:null
# 解释:调用函数后,输入的数组将被修改为:[1,0,0,2,3,0,0,4]
# 示例 2:
# 输入:[1,2,3]
# 输出:null
# 解释:调用函数后,输入的数组将被修改为:[1,2,3]
#me
class Solution(object):
def duplicateZeros(self, arr):
i = 0
while i < len(arr):
if arr[i] == 0:
arr.insert(i,0)
arr.pop()
i+=2
else:
i+=1

83.思路:threading线程方法
# 我们提供了一个类:
# public class Foo {
#   public void one() { print("one"); }
#   public void two() { print("two"); }
#   public void three() { print("three"); }
# }
# 三个不同的线程将会共用一个 Foo 实例。
# 线程 A 将会调用 one() 方法
# 线程 B 将会调用 two() 方法
# 线程 C 将会调用 three() 方法
# 请设计修改程序,以确保 two() 方法在 one() 方法之后被执行,three() 方法在 two() 方法之后被执行。
# 示例 1:
# 输入: [1,2,3]
# 输出: "onetwothree"
# 解释:
# 有三个线程会被异步启动。
# 输入 [1,2,3] 表示线程 A 将会调用 one() 方法,线程 B 将会调用 two() 方法,线程 C 将会调用 three() 方法。
# 正确的输出是 "onetwothree"。
# 示例 2:
# 输入: [1,3,2]
# 输出: "onetwothree"
# 解释:
# 输入 [1,3,2] 表示线程 A 将会调用 one() 方法,线程 B 将会调用 three() 方法,线程 C 将会调用 two() 方法。
# 正确的输出是 "onetwothree"。
#other
import threading
class Foo:
def __init__(self):
self.b1 = threading.Event()
self.b2 = threading.Event()
def first(self, printFirst):
printFirst()
self.b1.set()
def second(self, printSecond):
self.b1.wait()
printSecond()
self.b2.set()
def third(self, printThird):
self.b2.wait()
printThird()

84.思路:判断字母个数是否相同且集合是否相同
# 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
# 示例 1:
# 输入: s = "anagram", t = "nagaram"
# 输出: true
# 示例 2:
# 输入: s = "rat", t = "car"
# 输出: false
#me
class Solution0(object):
def isAnagram(self, s, t):
return [s.count(i) for i in set(s)] == [t.count(j) for j in set(t)] and set(s)==set(t)
#other
import collections
class Solution1(object):
def isAnagram(self, s, t):
return collections.Counter(s) == collections.Counter(t)

85.思路:直述题意
# 判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
# 示例 1:
# 输入: 121
# 输出: true
# 示例 2:
# 输入: -121
# 输出: false
# 解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
# 示例 3:
# 输入: 10
# 输出: false
# 解释: 从右向左读, 为 01 。因此它不是一个回文数。
#me
class Solution(object):
def isPalindrome(self, x):
return str(x) == str(x)[::-1]

86.思路:str.count方法
# 给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。
# 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。
# 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
# 示例 1:
# 给定 nums = [3,2,2,3], val = 3,
# 函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。
# 你不需要考虑数组中超出新长度后面的元素。
# 示例 2:
# 给定 nums = [0,1,2,2,3,0,4,2], val = 2,
# 函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。
# 注意这五个元素可为任意顺序。
# 你不需要考虑数组中超出新长度后面的元素。
#me
class Solution(object):
def removeElement(self, nums, val):
i = nums.count(val)
while i:
nums.remove(val)
i-=1

87.思路:排序+前半部分人去A,后半部分去B
# 公司计划面试 2N 人。第 i 人飞往 A 市的费用为 costs[i][0],飞往 B 市的费用为 costs[i][1]。
# 返回将每个人都飞到某座城市的最低费用,要求每个城市都有 N 人抵达。
# 示例:
# 输入:[[10,20],[30,200],[400,50],[30,20]]
# 输出:110
# 解释:
# 第一个人去 A 市,费用为 10。
# 第二个人去 A 市,费用为 30。
# 第三个人去 B 市,费用为 50。
# 第四个人去 B 市,费用为 20。
# 最低总费用为 10 + 30 + 50 + 20 = 110,每个城市都有一半的人在面试。
#other
class Solution(object):
def twoCitySchedCost(self, costs):
return sum((p[0] for i, p in enumerate(sorted(costs, key=lambda x: x[0] - x[1])) if i < len(costs) // 2)) + sum((p[1] for i, p in enumerate(sorted(costs, key=lambda x: x[0] - x[1])) if i >= len(costs) // 2))

88.思路:动态规划
# 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
# 设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
# 注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
# 示例 1:
# 输入: [7,1,5,3,6,4]
# 输出: 7
# 解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
#   随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。
# 示例 2:
# 输入: [1,2,3,4,5]
# 输出: 4
# 解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
#   注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。
#   因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。
# 示例 3:
# 输入: [7,6,4,3,1]
# 输出: 0
# 解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。
#other
# 股票买卖策略
# 单独交易日: 设今天价格 p_1p1、明天价格 p_2p2,则今天买入、明天卖出可赚取金额 p_2 - p_1p2−p 1(负值代表亏损)。
# 连续上涨交易日: 设此上涨交易日股票价格分别为 p_1, p_2, ... , p_n ,则第一天买最后一天卖收益最大,即 p_n - p_1;等价于每天都买卖,即p_n - p_1=(p_2 - p_1)+(p_3 - p_2)+...+(p_n - p_{n-1})
# 连续下降交易日: 则不买卖收益最大,即不会亏钱。
# 算法流程:
# 遍历整个股票交易日价格列表 price,策略是所有上涨交易日都买卖(赚到所有利润),所有下降交易日都不买卖(永不亏钱)。
# 设 tmp 为第 i-1 日买入与第 i 日卖出赚取的利润,即 tmp = prices[i] - prices[i - 1] ;
# 当该天利润为正 tmp > 0,则将利润加入总利润 profit;当利润为 00 或为负,则直接跳过;
# 遍历完成后,返回总利润 profit。
class Solution(object):
def maxProfit(self, prices):
profit = 0
for i in range(1, len(prices)):
tmp = prices[i] - prices[i - 1]
if tmp > 0:
profit += tmp
return profit

89.思路:先用任意数字检验一下,发现如果是快乐数 最终会收敛到1, 如果不是快乐数 最终会出现4 16 37 58 89 145 42 20循环
# 编写一个算法来判断一个数是不是“快乐数”。
# 一个“快乐数”定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是无限循环但始终变不到 1。如果可以变为 1,那么这个数就是快乐数。
# 示例: 
# 输入: 19
# 输出: true
# 解释:
# 12 + 92 = 82
# 82 + 22 = 68
# 62 + 82 = 100
# 12 + 02 + 02 = 1
#me
class Solution(object):
def isHappy(self, n):
while 1:
n = sum([int(i)**2 for i in str(n)])
if n == 4:
return False
if n == 1:
return True

90.思路:比较计数
# 如果单词列表(words)中的一个单词包含牌照(licensePlate)中所有的字母,那么我们称之为完整词。在所有完整词中,最短的单词我们称之为最短完整词。
# 单词在匹配牌照中的字母时不区分大小写,比如牌照中的 "P" 依然可以匹配单词中的 "p" 字母。
# 我们保证一定存在一个最短完整词。当有多个单词都符合最短完整词的匹配条件时取单词列表中最靠前的一个。
# 牌照中可能包含多个相同的字符,比如说:对于牌照 "PP",单词 "pair" 无法匹配,但是 "supper" 可以匹配。
# 示例 1:
# 输入:licensePlate = "1s3 PSt", words = ["step", "steps", "stripe", "stepple"]
# 输出:"steps"
# 说明:最短完整词应该包括 "s"、"p"、"s" 以及 "t"。对于 "step" 它只包含一个 "s" 所以它不符合条件。同时在匹配过程中我们忽略牌照中的大小写。
# 示例 2:
# 输入:licensePlate = "1s3 456", words = ["looks", "pest", "stew", "show"]
# 输出:"pest"
# 说明:存在 3 个包含字母 "s" 且有着最短长度的完整词,但我们返回最先出现的完整词。
#me 比较计数
class Solution(object):
def shortestCompletingWord(self, licensePlate, words):
licensePlateList = [str(i).lower() for i in licensePlate if i.isalpha()]
results = []
for word in words:
wordList = [str(j).lower() for j in word if j.isalpha()]
flag = 1
for s in set(licensePlateList):
if wordList.count(s) < licensePlateList.count(s):
flag = 0
if flag:
results.append(word)
minlength = min([len(result) for result in results])
return [result for result in results if len(result)==minlength][0]
91.思路:未知
# 给定平面上 n 对不同的点,“回旋镖” 是由点表示的元组 (i, j, k) ,其中 i 和 j 之间的距离和 i 和 k 之间的距离相等(需要考虑元组的顺序)。
# 找到所有回旋镖的数量。你可以假设 n 最大为 500,所有点的坐标在闭区间 [-10000, 10000] 中。
# 示例:
# 输入:
# [[0,0],[1,0],[2,0]]
# 输出:
# 2
# 解释:
# 两个回旋镖为 [[1,0],[0,0],[2,0]] 和 [[1,0],[2,0],[0,0]]
#other
import collections
class Solution(object):
def numberOfBoomerangs(self, points):
f = lambda x1, y1: sum(t * t - t for t in collections.Counter((x2 - x1) ** 2 + (y2 - y1) ** 2 for x2, y2 in points).values())
return sum(f(x1, y1) for x1, y1 in points)

92.思路:转化为字符串
# 给定一个二进制数组, 计算其中最大连续1的个数。
# 示例 1:
# 输入: [1,1,0,1,1,1]
# 输出: 3
# 解释: 开头的两位和最后的三位都是连续1,所以最大连续1的个数是 3.
#me
class Solution(object):
def findMaxConsecutiveOnes(self, nums):
strnumsList = ''.join([str(num) for num in nums]).split('0')
return max([len(i) for i in strnumsList])
#other
def findMaxConsecutiveOnes(nums):
for i in range(1, len(nums)):
nums[i] = nums[i] + nums[i - 1] if nums[i] and nums[i - 1] else nums[i]
return max(nums)

93.思路:集合减法
# 给定一个范围在  1 ≤ a[i] ≤ n ( n = 数组大小 ) 的 整型数组,数组中的元素一些出现了两次,另一些只出现一次。
# 找到所有在 [1, n] 范围之间没有出现在数组中的数字。
# 您能在不使用额外空间且时间复杂度为O(n)的情况下完成这个任务吗? 你可以假定返回的数组不算在额外空间内。
# 示例:
# 输入:
# [4,3,2,7,8,2,3,1]
# 输出:
# [5,6]
#me
class Solution(object):
def findDisappearedNumbers(self, nums):
return list(set(range(1,len(nums)+1))-set(nums))
94.思路:直述题意
# 给定一个单词,你需要判断单词的大写使用是否正确。
# 我们定义,在以下情况时,单词的大写用法是正确的:
# 全部字母都是大写,比如"USA"。
# 单词中所有字母都不是大写,比如"leetcode"。
# 如果单词不只含有一个字母,只有首字母大写, 比如 "Google"。
# 否则,我们定义这个单词没有正确使用大写字母。
# 示例 1:
# 输入: "USA"
# 输出: True
# 示例 2:
# 输入: "FlaG"
# 输出: False
#me
class Solution(object):
def detectCapitalUse(self, word):
if len([i for i in word if i.isupper()]) == len(word):
return True
elif word[0].isupper() and len([i for i in word if i.isupper()])==1:
return True
elif len([i for i in word if i.isupper()])==0:
return True
else:
return False

95.思路:举例+递归
# 报数序列是一个整数序列,按照其中的整数的顺序进行报数,得到下一个数。其前五项如下:
# 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"
#other
# 思路:
# 首先举个例子理解题意,对于4来说: 观察3对应的输出为21,1个2和1个1,所以4对应的报数为1211
# 这样,自然可以想到利用递归的方式来求解第n个数对应的输出,主要需要解决的问题在于具体计数部分:
# 举例:也即给定:1112222112如何计数得 3个1,4个2,2个1,1个2
# 1112222112-->31422112
#other
class Solution:
def countAndSay(self, n):
if n == 1:
return "1"
return self.bs(self.countAndSay(n - 1))

def bs(self, string):
lis = list(string)
lis.append('0') # 末尾补一个,方便后续计数
lis1 = []
re = 0
i = 0
while i < len(lis) - 1:
if lis[i] != lis[i + 1]:
lis1.append(str(i + 1 - re)) # 当前计录的值的个数
lis1.append(lis[i]) # 当前记录的值
re = i + 1
i = i + 1
s = ''.join(lis1) # 列表转字符串
return s

96.思路:集合减法
# 给定一个包含 0, 1, 2, ..., n 中 n 个数的序列,找出 0 .. n 中没有出现在序列中的那个数。
# 示例 1:
# 输入: [3,0,1]
# 输出: 2
# 示例 2:
# 输入: [9,6,4,2,3,5,7,0,1]
# 输出: 8
#me
class Solution(object):
def missingNumber(self, nums):
return list(set(range(len(nums)+1))-set(nums))[0]

97.思路:情景模拟
# 在柠檬水摊上,每一杯柠檬水的售价为 5 美元。
# 顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。
# 每位顾客只买一杯柠檬水,然后向你付 5 美元、10 美元或 20 美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5 美元。
# 注意,一开始你手头没有任何零钱。
# 如果你能给每位顾客正确找零,返回 true ,否则返回 false 。
# 示例 1:
# 输入:[5,5,5,10,20]
# 输出:true
# 解释:
# 前 3 位顾客那里,我们按顺序收取 3 张 5 美元的钞票。
# 第 4 位顾客那里,我们收取一张 10 美元的钞票,并返还 5 美元。
# 第 5 位顾客那里,我们找还一张 10 美元的钞票和一张 5 美元的钞票。
# 由于所有客户都得到了正确的找零,所以我们输出 true。
# 示例 2:
# 输入:[5,5,10]
# 输出:true
# 示例 3:
# 输入:[10,10]
# 输出:false
# 示例 4:
# 输入:[5,5,10,10,20]
# 输出:false
# 解释:
# 前 2 位顾客那里,我们按顺序收取 2 张 5 美元的钞票。
# 对于接下来的 2 位顾客,我们收取一张 10 美元的钞票,然后返还 5 美元。
# 对于最后一位顾客,我们无法退回 15 美元,因为我们现在只有两张 10 美元的钞票。
# 由于不是每位顾客都得到了正确的找零,所以答案是 false。
#other
#思路:方法:模拟情景
# 思路与算法
# 让我们尝试模拟给每个购买柠檬水的顾客进行找零的过程。最初,我们从没有 5 美元钞票也没有 10 美元钞票的情况开始。
# 如果顾客支付了 5 美元钞票,那么我们就得到 5 美元的钞票。
# 如果顾客支付了 10 美元钞票,我们必须找回一张 5 美元钞票。如果我们没有 5 美元的钞票,答案就是 false,因为我们无法正确找零。
# 如果顾客支付了 20 美元钞票,我们必须找回 15 美元。
# 如果我们有一张 10 美元和一张 5 美元,那么我们总会更愿意这样找零,这比用三张 5 美元进行找零更有利。
# 否则,如果我们有三张 5 美元的钞票,那么我们将这样找零。
# 否则,我们将无法给出总面值为 15 美元的零钱,答案是 false。
class Solution(object):
def lemonadeChange(self, bills):
five = ten = 0
for bill in bills:
if bill == 5:
five += 1
elif bill == 10:
if not five: return False
five -= 1
ten += 1
else:
if ten and five:
ten -= 1
five -= 1
elif five >= 3:
five -= 3
else:
return False
return True

98.思路:内置函数
# 不使用运算符 + 和 - ​​​​​​​,计算两整数 ​​​​​​​a 、b ​​​​​​​之和。
# 示例 1:
# 输入: a = 1, b = 2
# 输出: 3
# 示例 2:
# 输入: a = -2, b = 3
# 输出: 1
#me
class Solution(object):
def getSum(self, a, b):
return sum([a,b])

99.思路:直述题意
# 给定一个字符串 S,返回 “反转后的” 字符串,其中不是字母的字符都保留在原地,而所有字母的位置发生反转。
# 示例 1:
# 输入:"ab-cd"
# 输出:"dc-ba"
# 示例 2:
# 输入:"a-bC-dEf-ghIj"
# 输出:"j-Ih-gfE-dCba"
# 示例 3:
# 输入:"Test1ng-Leet=code-Q!"
# 输出:"Qedo1ct-eeLg=ntse-T!"
#me
class Solution(object):
def reverseOnlyLetters(self, S):
alpha = []
for n,s in enumerate(S):
if s.isalpha():
alpha.append(str(s))
reserveS = list(alpha)
listS = list(S)
for i in range(len(S)):
if listS[i].isalpha():
listS[i] = reserveS[-1]
reserveS.pop()
return ''.join(listS)

100.解题思路:题意可理解位每次让一个值减去1,使得所有的值相等,那理想情况就是每个值最终等于最小值。那么题目就转换为所有值减去最小值的和。
# 给定一个长度为 n 的非空整数数组,找到让数组所有元素相等的最小移动次数。每次移动可以使 n - 1 个元素增加 1。
# 示例:
# 输入:
# [1,2,3]
# 输出:
# 3
# 解释:
# 只需要3次移动(注意每次移动会增加两个元素的值):
# [1,2,3] => [2,3,3] => [3,4,3] => [4,4,4]
#other
class Solution:
def minMoves(self, nums):
minvalue = min(nums)
count = 0
for i in nums:
count += i - minvalue
return count

你可能感兴趣的:(Leetcode简单题81~100)