【Leedcode】经典习题分析(1)

今后我将会做Leedcode专题,将我做题的分析和代码记录下来。所有题目都来源于https://leetcode-cn.com。所有的语言都用python编写。

本篇难度:简答

习题一:两数之合

题目:

1.给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。

示例:

给定 nums = [2, 7, 11, 15], target = 9,因为 nums[0] + nums[1] = 2 + 7 = 9,所以返回 [0, 1]

解题思路:

①题中很明确的说只有一个输出结果,因此不可能出现列表中有多个相同的元素的情况。

②我们可以采用循环的方法逐个查找,但是考虑到耗时问题,不能暴力查找。

③核心:num1+num2=target

#  方法1:

def twoSum(nums, target):
    lens = len(nums)
    j=-1
    for i in range(lens):
        if (target - nums[i]) in nums:
            #如果num2=num1,且nums中只出现了一次,说明找到是num1本身。
            if (nums.count(target - nums[i]) == 1)&(target - nums[i] == nums[i]):
                continue
            else:
                j = nums.index(target - nums[i],i+1) #index(x,i+1)是从num1后的序列后找num2                
                break
    if j>0:
        return [i,j]
    else:
        return []


#  可以学到:
#  nums.count(x)可以得到列表nums中x出现的次数
#  nums.index(x)返回的是列表nums中元素x的索引
----------------------------------------------------------------------------
#  方法2:

def twoSum(nums, target):
    lens = len(nums)
    j=-1
    for i in range(1,lens):
        temp = nums[:i]
        if (target - nums[i]) in temp:
            j = temp.index(target - nums[i])
            break
    if j>=0:
        return [j,i]
-----------------------------------------------------------------------------
#  方法3:

def twoSum(nums, target):
    hashmap={}
    for ind,num in enumerate(nums):
        hashmap[num] = ind
    for i,num in enumerate(nums):
        j = hashmap.get(target - num)
        if j is not None and i!=j:
            return [i,j]
#  可以学到:
#  这里通过字典来模拟哈希查询的过程
#  当用for循环查找索引和值的时候,可以用enumerate(nums),返回索引和值
#  hashmap.get(x),返回字典中key为x的value值
-----------------------------------------------------------------------------
#  方法4:
#  这是方法3的优化
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        hashmap={}
        for i,num in enumerate(nums):
            if hashmap.get(target - num) is not None:
                if i<hashmap.get(target - num):
                    return [i,hashmap.get(target - num)]
                else:
                    return [hashmap.get(target - num),i]
            hashmap[num] = i

习题二:整数反转

题目:

给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。注意:假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231,  231 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。

示例:

输入: 123  输出: 321; 输入: -123  输出: -321  ;输入: 120  输出: 21

解题思路 :

将整数先去符号,然后转换成字符串或者列表,将其反转。

#  方法1:
#  整数去符号—变成字符串—变成列表—反转—再变成字符串
class Solution:
    def reverse(self, x: int) -> int:
        #将整数的绝对值转换成字符串
        s=str(abs(x))
        #字符串变成列表
        s=list(s)
        #列表反转
        s.reverse()
        #列表变成字符串
        s=''.join(s)
        #如果输入整数是负数,增加负号
        if x <0:
            s ='-' + s
        #转换为整数
        result = int(s)
        #判断是否溢出
        if result>=-2**31 and result<=2**31-1:
            return result
        else:
            return 0

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

#  可以学到:
#  整数、字符串、列表之间的转换关系要注意,熟悉操作以便简化代码

习题三:回文数

题目:

判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。

示例:

输入: -121 输出: false 解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。

解题思路:

此题和第二题类似,都是采用字符串反转来判断。这里要注意的是函数的返回值是一个已经定义的变量求得的结果,不能用return false来表示,因为false没有定义。

#  方法1:

#  此方法可以在leedcode中通过
class Solution:
    def isPalindrome(self, x: int) -> bool:
        # 转换成字符串
        x=str(x)
        # 字符串反转
        s=x[::-1]
        return x==s
---------------------------------------------------------
#  方法2:

#  此方法只能在编译器通过 ,因为leedcode中会把'flase'和'true'当成字符串,而不是布尔值
class Solution:
    def isPalindrome(self, x: int) -> bool:
        if x < 0:
            return 'false'
        else:
            s1=str(x)
            s2=s1[::-1]
            if s1==s2:
                return 'true'
            else:
                return 'false'

习题四:罗马数字转整数

题目:

罗马数字包含以下七种字符: I, V, X, LCD 和 M。

字符          数值
I             1
V             5
X             10
L             50
C             100
D             500
M             1000

例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做  XXVII, 即为 XX + V + II 。通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:

  • I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
  • X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。 
  • C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。

给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。

示例:

输入: "MCMXCIV"
输出: 1994
解释: M = 1000, CM = 900, XC = 90, IV = 4.

解题思路:

①用字典将这些key-value对存入其中。

②通过观察,我们可以发现,正常来说大的字符在前,小的字符在后。由于6种特殊情况是小的字符在大的字符前面,因此当从左到右遍历的时候,碰到s[i]<s[i+1]就用sum减去x[i]即可。

class Solution:
    def romanToInt(self, s: str) -> int:
        dic={'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
        sum=0
        for i in range(len(s)-1):
            if dic[s[i]]>=dic[s[i+1]]:
                sum=sum+dic[s[i]]
            else:
                sum=sum-dic[s[i]]
        sum=sum+dic[s[-1]]
        return sum

习题五:最长公共前缀

题目:

编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 ""。所有输入只包含小写字母 a-z 。

示例:

输入: ["flower","flow","flight"]
输出: "fl"

解题思路:

①两两比较

②为了节约空间,每次都是比较列表最后两个字符串,把比较的结果放在列表倒数第二个位置,把列表最后一个位置元素删除。

#   方法1:
class Solution:
    def longestCommonPrefix(self, strs: List[str]) -> str:
        # 空串
        if not strs:
            return ''
        # 只有1个元素,自己和自己比较
        elif len(strs)==1:
            return strs[0]
        else:
            # 等于1的时候,就是最后的结果了
            while len(strs)!=1:
                a=strs[-1]
                b=strs[-2]
                i=0
                res=''
                while i<len(a) and i<len(b):
                    if a[i]==b[i]:
                        res=res+a[i]
                        i+=1
                    else:
                        break
                strs[-2]=res
                strs.pop()
            return res
--------------------------------------------------------------
#  方法2:
class Solution(object):
    def longestCommonPrefix(self, strs):
        ans = ''
        for i in zip(*strs):
            # set(i)是去重,如果都一样的话 ,只保留一个,因此结果为1
            if len(set(i)) == 1:
                # 如果去重成功,则是公共前缀,因此要取一个,这里取第一个最简单
                ans += i[0]
            else:
                break
        return ans

#  可以学到:
#  zip(*strs)返回一个以元组为元素的列表,其中第i个元组包含每个参数序列的第i个元素。返回的列表长度被截断为最短的参数序列的长度。

# 如下是zip(*a)的结果

a= ["flower","flow","flight"]
b=zip(*a)
for i in b:
    print(i)

('f', 'f', 'f')
('l', 'l', 'l')
('o', 'o', 'i')
('w', 'w', 'g')

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值