leetcode(75,455,69,241,160)

75.颜色分类(中等)

这题又被称为荷兰国旗问题。

给定一个包含红色、白色和蓝色,一共n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

此题中,我们使用整数 0、1 和 2 分别表示红色、白色和蓝色。

注意:

不能使用代码库中的排序函数来解决这道题。

示例:
输入: [2,0,2,1,1,0]
输出: [0,0,1,1,2,2]
解法一:

题目中只会出现0,1,2,其实就是要把题目中的0,1,2按照升序排好就可以了,我们可以从头遍历输入的数组,碰到是0,就把数组对应位置改为0,碰到1,就计数,遍历完后,0就已经排好了,按照记录的1的数目把1放到0的后面,然后把剩下位置改为2就可以了。代码如下:

class Solution(object):
    def sortColors(self, nums):
        """
        :type nums: List[int]
        :rtype: None Do not return anything, modify nums in-place instead.
        """
        i, j = 0, 0
        for s in nums:
            if s == 0:
                nums[i] = 0
                i += 1
            elif s == 1:
                j += 1
        for s in range(i, i + j):
            nums[s] = 1
        for s in range(i + j, len(nums)):
            nums[s] = 2
解法二:

用三个指针p0,p2,curr来分别表示最右边一个0,最左边一个2,以及当前元素。

当curr=0时,把p0与curr的元素互换,并且两个指针都加1,如果curr=2,则互换p2与curr,并把p2减一,但是注意curr不加一,因为交换过来的元素还要判断一次,如果curr=1,则curr加1即可。

class Solution(object):
    def sortColors(self, nums):
        """
        :type nums: List[int]
        :rtype: None Do not return anything, modify nums in-place instead.
        """
        p0 = 0
        p2 = len(nums)-1
        curr = 0
        while curr <= p2:
            if nums[curr] == 2:
                nums[p2], nums[curr] = nums[curr], nums[p2]
                p2 -= 1
            elif nums[curr] == 0:
                nums[p0], nums[curr] = nums[curr], nums[p0]
                curr += 1
                p0 += 1
            else:
                curr += 1

455.分发饼干(简单)

假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。对每个孩子 i ,都有一个胃口值gi ,这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j ,都有一个尺寸 sj。如果 sj >= gi,我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。

注意:

你可以假设胃口值为正。
一个小朋友最多只能拥有一块饼干。

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

输出: 1

解释: 
你有三个孩子和两块小饼干,3个孩子的胃口值分别是:1,2,3。
虽然你有两块小饼干,由于他们的尺寸都是1,你只能让胃口值是1的孩子满足。
所以你应该输出1。
示例2:
输入: [1,2], [1,2,3]

输出: 2

解释: 
你有两个孩子和三块小饼干,2个孩子的胃口值分别是1,2。
你拥有的饼干数量和尺寸都足以让所有孩子满足。
所以你应该输出2.
解法一:

首先把两个list进行升序排列,之后从第一个孩子和第一块饼干开始判断,如果g[i]>s[j],说明不能满足孩子的胃口,j+1,否则j,i,count都加一,循环条件是某一个列表遍历完。这里注意的是循环条件其实可以是两个一起制定的,用and连接就好,方便很多。

class Solution(object):
    def findContentChildren(self, g, s):
        """
        :type g: List[int]
        :type s: List[int]
        :rtype: int
        """
        g.sort()
        s.sort()
        i = 0
        j = 0
        count = 0
        while i < len(g) and j < len(s):
            if g[i] > s[j]:
                j += 1
            else:
                count += 1
                i += 1
                j += 1
        return count
解法二:

可以改的更加优雅一些,观察上面的代码,可以发现无论什么操作j都要加一,且i和count都是同步的,所以可以这样精简。

class Solution(object):
    def findContentChildren(self, g, s):
        """
        :type g: List[int]
        :type s: List[int]
        :rtype: int
        """
        g.sort()
        s.sort()
        i = 0
        j = 0
        while i < len(g) and j < len(s):
            if g[i] <= s[j]:
                i += 1
            j += 1
        return i

69.x的平方根 (简单)

实现 int sqrt(int x) 函数。

计算并返回 x 的平方根,其中 x 是非负整数。

由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。

示例1:
输入: 4
输出: 2
示例2:
输入: 8
输出: 2
说明: 8 的平方根是 2.82842..., 
     由于返回类型是整数,小数部分将被舍去。
解法一:

使用二分法,但是二分法的边界问题很恶心,一不小心就进入了死循环

class Solution(object):
    def mySqrt(self, x):
        """
        :type x: int
        :rtype: int
        """
        left = 0
        right = x // 2 + 1  #为了照顾输入1
        while left<right:
            mid = (left+right) // 2 + 1  
            square = mid*mid
            if square == x:
                return mid
            elif square>x:
                right = mid-1
            else:
                left = mid
        return left
            
解法二:

用牛顿迭代法,求a的平方根,相当于求

f(x) = x^2 -a

当f(x)=0时的根

image
这个函数的导函数是2x,也就是我猜的每一个x等于x-f(x)/2x,把f(x)=x^2-a带进去,可以得到迭代公式x = 1/2(x+a/x),进行迭代就可以,终止迭代的条件是前后两次的x值相差小于1*10^-6,即返回x。

class Solution(object):
    def mySqrt(self, x):
        """
        :type x: int
        :rtype: int
        """
        cur = x #这个数随便写,多少都行
        while True:
            pre = cur
            cur = (cur + x/cur) / 2
            if abs(cur-pre)<1e-6:
                return int(cur)

241.为运算表达式设计优先级(中等)

给定一个含有数字和运算符的字符串,为表达式添加括号,改变其运算优先级以求出不同的结果。你需要给出所有可能的组合的结果。有效的运算符号包含 +, - 以及 * 。

示例1:
输入: "2-1-1"
输出: [0, 2]
解释: 
((2-1)-1) = 0 
(2-(1-1)) = 2
示例2:
输入: "2*3-4*5"
输出: [-34, -14, -10, -10, 10]
解释: 
(2*(3-(4*5))) = -34 
((2*3)-(4*5)) = -14 
((2*(3-4))*5) = -10 
(2*((3-4)*5)) = -10 
(((2*3)-4)*5) = 10

解法一:

采用分治+递归的思想,把字符串按照运算符号分为左边和右边,一直分到只剩单独一个数字时,根据输入的符号进行运算,简单的说就是,函数返回的就是目前输入的字符串的所有的运算结果可能。

class Solution(object):
    def diffWaysToCompute(self, input):
        """
        :type input: str
        :rtype: List[int]
        """
        if input.isdigit():
            return [int(input)]
        res = []
        for i in range(len(input)):
            if input[i] in "+-*":
                res1 = self.diffWaysToCompute(input[:i])
                res2 = self.diffWaysToCompute(input[i+1:])
                for l in res1:
                    for r in res2:
                        res.append(self.helper(l, r, input[i]))
        return res
    def helper(self, a, b, op):
        if op == "+":
            return a+b
        elif op == "-":
            return a-b
        else:
            return a*b
            
    #helper函数也可以这么写:
    """
        def helper(self, a, b, op):
            return {
                    '+': a + b,
                    '-': a - b,
                    '*': a * b
                }[op]
    """

160.相交链表(中等)

编写一个程序,找到两个单链表相交的起始节点。

如下面的两个链表:
image
在节点 c1 开始相交。

示例1:

image

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出:Reference of the node with value = 8
输入解释:相交节点的值为 8 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。
示例2:

image

输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
输出:Reference of the node with value = 2
输入解释:相交节点的值为 2 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 [3,2,4]。在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。
示例3:

image

输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
输出:null
输入解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。
解释:这两个链表不相交,因此返回 null。
解法一:

首先计算出两个链表的长度差,把长的那一条的指针往后移动差值步,之后两个链表一起向后遍历,当遇到一样的值时就是相交的节点。

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

class Solution(object):
    def getIntersectionNode(self, headA, headB):
        """
        :type head1, head1: ListNode
        :rtype: ListNode
        """
        a = headA
        b = headB
        len_a = 0
        len_b = 0
        while a:
            a = a.next
            len_a += 1
        while b:
            b = b.next
            len_b += 1
        if a != b:
            return None
        a = headA
        b = headB
        if len_a > len_b:
            for _ in range(len_a-len_b):
                a = a.next
        elif len_b > len_a:
            for _ in range(len_b - len_a):
                b = b.next
        while a!=b:
            a = a.next
            b = b.next
        return a
解法二:

其实还是消除长度差,不过我们可以把两个链表拼在一起,一个长-短,一个短-长,当两个指针相同时即达成条件,如下图所示:
image

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

class Solution(object):
    def getIntersectionNode(self, headA, headB):
        """
        :type head1, head1: ListNode
        :rtype: ListNode
        """
        a = headA
        b = headB
        while a!=b:
            a = a.next if a else headB
            b = b.next if b else headA
        return a
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值