【程序人生】leetcode(二)

说在前面

这篇博客中部分题目答案来自leetcode评论区,不是本人原创。感谢原作者的工作。这里记录在这篇博客中,方便日后回顾、学习

罗马数字转整数(原创)

罗马数字包含以下七种字符: I, V, X, L,C,D 和 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 的范围内。

class Solution:
    def romanToInt(self, s: str) -> int:
        hash_map = {"I":1, "V":5, "X":10, "L":50, "C":100, "D":500, "M":1000}
        value = 0
        s = list(s[::-1])
        for i, each in enumerate(s):
            if i == 0:
                value = value + hash_map[each]
            else:
                if hash_map[each] >= hash_map[s[i-1]]:
                    value = value + hash_map[each]
                else:
                    value = value - hash_map[each]

        return value

整数转罗马数字(转载)

罗马数字包含以下七种字符: I, V, X, L,C,D 和 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的范围内。

class Solution:
    def intToRoman(self, num: int) -> str:
        hash_map = {"M":1000, "CM":900, "D":500, "CD":400, "C":100, "XC":90, 
                    "L":50, "XL":40, "X":10, "IX":9, "V":5, "IV":4, "I":1}
        
        string = ""
        while num>0:
            for key in hash_map:
                while num>=hash_map[key]:
                    num-=hash_map[key]
                    string +=key

        return string

盛水最多的容器(转载)

给你n个非负整数a1a_1a2a_2,…,ana_n,每个数代表座标中的一个点(i,ai)(i, a_i)。在座标内画n条垂直线,垂直线i的两个端点分别为(i,ai)(i, a_i)(i,0)(i, 0)。找出其中的两条线,使得它们与x轴共同构成的容器可以容纳最多的水。

说明:你不能倾斜容器,且n的值至少为 2。
在这里插入图片描述
图中垂直线代表输入数组[1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为49。

class Solution:
    def maxArea(self, height: List[int]) -> int:
        left = 0
        right = len(height) - 1
        maxArea = 0
        while left < right:
            b = right - left
            if height[left] < height[right]:
                h = height[left]
                left += 1
            else:
                h = height[right]
                right -= 1
            area = b*h
            if maxArea < area:
                maxArea = area
        return maxArea

三数之和(转载)

给你一个包含n个整数的数组nums,判断nums中是否存在三个元素a,b,c,使得a + b + c = 0?请你找出所有满足条件且不重复的三元组。

注意:答案中不可以包含重复的三元组。

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        # 升序排列
        nums.sort()
        res =[]
    
        for i in range(len(nums)):
            if i == 0 or nums[i]>nums[i-1]:
                l = i+1
                r = len(nums)-1
                while l < r:
                    s = nums[i] + nums[l] +nums[r]
                    if s == 0:
                        res.append([nums[i],nums[l],nums[r]])
                        l += 1
                        r -= 1
                        while l < r and nums[l] == nums[l-1]:
                            l += 1
                        while r > l and nums[r] == nums[r+1]:
                            r -= 1
                    elif s > 0:
                        r -= 1
                    else :
                        l += 1
        return res
  1. 将数组排序
  2. 定义三个指针,i、j、k。遍历i,那么这个问题就可以转化为在i之后的数组中寻找nums[j]+nums[k]=nums[i]nums[j]+nums[k]=-nums[i]这个问题,也就将三数之和问题转变为二数之和

合并两个有序链表(原创)

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

# 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:
        if l1 is None:
            return l2
        if l2 is None:
            return l1

        # 遍历a, 插入start
        if l1.val >= l2.val:
            a = l1
            start = l2
        else:
            a = l2
            start = l1

        node = start
        while a is not None:
            try:
                while not (node.val <= a.val <= node.next.val):
                    node = node.next
            
                linshi = ListNode(a.val)
                linshi.next = node.next
                node.next = linshi

            except AttributeError:
                node.next = a
                return start
                
            a = a.next

        return start

电话号码的字母组合(原创)

给定一个仅包含数字2-9的字符串,返回所有它能表示的字母组合。

给出数字到字母的映射如下(与电话按键相同)。注意1不对应任何字母。
在这里插入图片描述

class Solution:
    def letterCombinations(self, digits: str) -> List[str]:
        hash_map = {2:["a", "b", "c"], 3:["d", "e", "f"], 
                    4:["g", "h", "i"], 5:["j", "k", "l"],
                    6:["m", "n", "o"], 7:["p", "q", "r", "s"],
                    8:["t", "u", "v"], 9:["w", "x", "y", "z"]}
        
        num = len(digits)
        result = []

        while num > 0:
            key = int(digits[0:1])
            digits = digits[1:]
            num = len(digits)

            if result == []:
                for each in hash_map[key]:
                    result.append(each)
            else:
                res = []
                for i in result:
                    for j in hash_map[key]:
                        res.append(i+j)
                result = res
                
        return result

两两交换链表中的节点(转载)

给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。

你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

示例:

给定 1->2->3->4, 你应该返回 2->1->4->3.

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

class Solution:
    def swapPairs(self, head: ListNode) -> ListNode:
        if (head is None) or (head.next is None):
            return head
        
        linshi = ListNode(head.next.val)
        linshi.next = head
        head.next = self.swapPairs(head.next.next)

        return linshi

使用递归来解决该题,主要就是递归的三部曲

  • 找终止条件:本题终止条件很明显,当递归到链表为空或者链表只剩一个元素的时候,没得交换了,自然就终止了。
  • 找返回值:返回给上一层递归的值应该是已经交换完成后的子链表。
  • 单次的过程因为递归是重复做一样的事情,所以从宏观上考虑,只用考虑某一步是怎么完成的。我们假设待交换的俩节点分别为head和next,next的应该接受上一级返回的子链表(参考第2步)。就相当于是一个含三个节点的链表交换前两个节点,就很简单了,想不明白的画画图就ok。

括号生成(转载)

数字n代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且有效的括号组合。

示例:

输入:n = 3
输出:[
“((()))”,
“(()())”,
“(())()”,
“()(())”,
“()()()”
]

class Solution:
    def generateParenthesis(self, n: int) -> List[str]:
        result = []
        def dfs(num_left, num_right, string):
            if num_left == 0 and num_right == 0:
                result.append(string)
                return
            
            if num_left > 0:
                dfs(num_left - 1, num_right, string + "(")
            if num_right > num_left:
                dfs(num_left, num_right - 1, string + ")")
        dfs(n, n, "")

        return result

有效的括号(转载)

给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。

有效字符串需满足:

  • 左括号必须用相同类型的右括号闭合。
  • 左括号必须以正确的顺序闭合。

注意空字符串可被认为是有效字符串。

class Solution:
    def isValid(self, s: str) -> bool:
        while (("[]" in s) or ("()" in s) or ("{}" in s)):
            s = s.replace("[]", "")
            s = s.replace("()", "")
            s = s.replace("{}", "")
        
        if s == "":
            return True
        else:
            return False

最接近的三数之和(原创)

给定一个包括n个整数的数组nums和一个目标值target。找出nums中的三个整数,使得它们的和与target最接近。返回这三个数的和。假定每组输入只存在唯一答案。

示例:

例如,给定数组 nums = [-1,2,1,-4], 和 target = 1.
与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).

class Solution:
    def threeSumClosest(self, nums: List[int], target: int) -> int:
        # 判断是不是最接近target
        res = 1000000000000000000
        # 返回结果
        result = 0

        # 升序排列
        nums.sort()
        
        for i, each in enumerate(nums[:-2]):
            linshi = nums[i+1:]
            # 左指针
            p1 = 0 
            # 右指针
            p2 = len(linshi) - 1
            
            if abs(each + linshi[p1] + linshi[p2] - target) == 0:
                return each + linshi[p1] + linshi[p2]
            
            if abs(each + linshi[p1] + linshi[p2] - target) < res:
                result = each + linshi[p1] + linshi[p2]
                res = abs(each + linshi[p1] + linshi[p2] - target)

            while p1 < p2:
                if (each + linshi[p1] + linshi[p2] - target) == 0:
                    return each + linshi[p1] + linshi[p2]
                
                if abs(each + linshi[p1] + linshi[p2] - target) < res:
                    result = each + linshi[p1] + linshi[p2]
                    res = abs(each + linshi[p1] + linshi[p2] - target)

                if (each + linshi[p1] + linshi[p2] - target) > 0:
                    p2 = p2 -1
                else:
                    p1 = p1 + 1
        
        return result

结语

如果您有修改意见或问题,欢迎留言或者通过邮箱和我联系。
手打很辛苦,如果我的文章对您有帮助,转载请注明出处。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章