力扣小记

平方数之和:给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 $a^2$ + $b^2$ = c。

  费马定理:

    1、任何形为$4n+1$的素数都能表示为两个平方数之和。

    2、如果两个整数都能表示为两个平方数之和,则它们的积也能表示为两个平方数之和。

      斐波那契恒等式:$(a^2+b^2)+(p^2+q^2) = (ap+bq)^2+(aq-bp)^2$

数字根:给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。

  原数: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
  数根: 1 2 3 4 5 6 7 8 9 1    2   3   4  5    6   7   8   9   1   2   3   4   5   6   7   8   9   1   2   3

  解法:对九取余即可

最低票价:

在一个火车旅行很受欢迎的国度,你提前一年计划了一些火车旅行。在接下来的一年里,你要旅行的日子将以一个名为 days 的数组给出。每一项是一个从 1 到 365 的整数。

火车票有三种不同的销售方式:

一张为期一天的通行证售价为 costs[0] 美元;
一张为期七天的通行证售价为 costs[1] 美元;
一张为期三十天的通行证售价为 costs[2] 美元。
通行证允许数天无限制的旅行。 例如,如果我们在第 2 天获得一张为期 7 天的通行证,那么我们可以连着旅行 7 天:第 2 天、第 3 天、第 4 天、第 5 天、第 6 天、第 7 天和第 8 天。

返回你想要完成在给定的列表 days 中列出的每一天的旅行所需要的最低消费。

1 <= days.length <= 365
1 <= days[i] <= 365
days 按顺序严格递增
costs.length == 3
1 <= costs[i] <= 1000

解法:动态规划

  动态规划的一般做法:

    1、建立连续的数组来记录数据,以下标的形式查找,但会消耗内存。

    2、递归的方法,找到动态方程。

题目解法:

  1、建立空间为365大小的连续数组,记录每天的花费,i表示第i天之前的总花费。

  2、没有旅行的第i天则是与第i - 1天相同

  3、取i - 1 、i - 7和i - 30的最小值。返回最后旅行的总花费。

 1 def mincostTickets(days, costs):
 2     
 3     re = [0] * 365
 4     i = 0
 5     for index in range(365):
 6         if i == len(days):
 7             break
 8         if index != days[i] - 1:
 9             re[index] = re[index - 1]
10             continue
11         
12         if days[i] - 1 < 0:
13             tmp1 = costs[0]
14         else:
15             tmp1 = re[days[i] - 2] + costs[0]
16         if days[i] - 7 < 0:
17             tmp2 = costs[1]
18         else:
19             tmp2 = re[days[i] - 8] + costs[1]
20         if days[i] - 30 < 0:
21             tmp3 = costs[2]
22         else:
23             tmp3 = re[days[i] - 31] + costs[2]
24         re[index] = min(tmp1,tmp2,tmp3)
25         i += 1
26     
27     return re[days[-1] - 1]

 

填充书架:

附近的家居城促销,你买回了一直心仪的可调节书架,打算把自己的书都整理到新的书架上。

你把要摆放的书 books 都整理好,叠成一摞:从上往下,第 i 本书的厚度为 books[i][0],高度为 books[i][1]。

按顺序 将这些书摆放到总宽度为 shelf_width 的书架上。

先选几本书放在书架上(它们的厚度之和小于等于书架的宽度 shelf_width),然后再建一层书架。重复这个过程,直到把所有的书都放在书架上。

需要注意的是,在上述过程的每个步骤中,摆放书的顺序与你整理好的顺序相同。 例如,如果这里有 5 本书,那么可能的一种摆放情况是:第一和第二本书放在第一层书架上,第三本书放在第二层书架上,第四和第五本书放在最后一层书架上。

每一层所摆放的书的最大高度就是这一层书架的层高,书架整体的高度为各层高之和。

以这种方式布置书架,返回书架整体可能的最小高度。

 

  1、创建数组来存储每一次放完书的最低高度,创建n + 1长度的数组,第一位为0,没有开始放书。

  2、放完第 i 本书后不断往前调整数的位置,逐渐与前一位的书放在同一层书架中,在宽度超出限制或者循环到第一本书则结束。

 1 class Solution:
 2     def minHeightShelves(self, books: List[List[int]], shelf_width: int) -> int:
 3 
 4         n = len(books)
 5         f = [0] * (n + 1)
 6         for index in range(n):
 7             high = f[index] + books[index][1] # 记录加入书后书架的高度 
 8             width = books[index][0]               # 新加入书的宽度
 9             h = books[index][1]                    # 书的高度          
10             for i in range(index - 1,-1,-1):      # 调整前面的书
11                 width += books[i][0]               # 与前面的书放在一起后的宽度
12                 if width > shelf_width:            # 超过限制则退出
13                     break
14                 h = max(h,books[i][1])           # 合并书到一起的最大高度
15                 high = min(high,f[i] + h)         # 取最小的高度
16             f[index + 1] = high
17         return f[-1]

 最大正方形:在一个由 0 和 1 组成的二维矩阵内,找到只包含 1 的最大正方形,并返回其面积。

  解法:

    1、d[i][j] 表示矩阵 i ,j 位置的最大面积的边长。

    2、动态方程:$d[i][j] = max(d[i - 1][j],d[i -1][j - 1],d[i][j - 1]) + 1$

 1 class Solution:
 2     def maximalSquare(self, matrix: List[List[str]]) -> int:
 3         if not matrix:
 4             return 0
 5         n,m = len(matrix),len(matrix[0])
 6         re = 0
 7         for i in range(n):
 8             for j in range(m):
 9                 if matrix[i][j] == '1':
10                     t1 = 0 if i - 1 < 0 else matrix[i - 1][j]
11                     t2 = 0 if i - 1 < 0 or j - 1 < 0 else matrix[i - 1][j - 1]
12                     t3 = 0 if j - 1 < 0 else matrix[i][j - 1]
13 
14                     matrix[i][j] = min(t1,t2,t3) + 1
15                     re = max(re,matrix[i][j])
16                 else:
17                     matrix[i][j] = 0
18         return re * re

 power:计算 x 的 n 次幂函数。

快速幂+递归:$x \to x^2 \to x^4 \to x^9 \to x^{19} \to x^{38} \to x^{77}$,在上述的过程中我们只需要知道是否需要多乘一个 x,

  1、当我们要计算 $x^n$时,我们可以先递归地计算出 $y = x^{[ n / 2 ]}$,其中 [ n / 2 ]表示对 a 进行下取整;

  2、根据递归计算的结果,如果$n$为偶数,那么$x^n = y^2$,如果 n 为奇数,那么$x^n = y^2 * x$。

  3、递归的边界为 $n = 0$,任意数的 0 次方均为 1

class Solution:
    def myPow(self, x: float, n: int) -> float:
        def quickMul(N):
            if N == 0:
                return 1.0
            y = quickMul(N // 2)
            return y * y if N % 2 == 0 else y * y * x
        
        return quickMul(n) if n >= 0 else 1.0 / quickMul(-n)

快速幂+迭代:

class Solution:
    def myPow(self, x: float, n: int) -> float:
        def quickMul(N):
            ans = 1.0
            # 贡献的初始值为 x
            x_contribute = x
            # 在对 N 进行二进制拆分的同时计算答案
            while N > 0:
                if N % 2 == 1:
                    # 如果 N 二进制表示的最低位为 1,那么需要计入贡献
                    ans *= x_contribute
                # 将贡献不断地平方
                x_contribute *= x_contribute
                # 舍弃 N 二进制表示的最低位,这样我们每次只要判断最低位即可
                N //= 2
            return ans
        
        return quickMul(n) if n >= 0 else 1.0 / quickMul(-n)

 滑动窗口的最大值:给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。

以一个队列来实现窗口的排序,队列的头部是最大值,新元素都会进入队列,但是将要进入的数比尾部的数大则尾部退出队列,不断重复直至保持队列的有序性。

def maxSlidingWindow(nums,k):
    deque = [];result = []               # deque也可以用collection里的双端队列实现
    for i in range(0, len(nums)):
        while deque and nums[i]>nums[deque[-1]]: # 只存有可能成为最大值的数字的index进deque
            deque.pop()                         # 尾部出队列
        deque.append(i)
        while i-deque[0]>k-1:                   # 如果相距超过窗口k长度则弃掉
            deque.pop(0)                        # 头部出队列
        if i >= k-1:                            # 数组的长度小于k则返回空值
            result.append(nums[deque[0]])       # 这过程中始终保持deque[0]为最大值的index
    return result


maxSlidingWindow([1,3,-1,-3,-2,3,6,7],3)

 最小栈:

设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。

push(x) —— 将元素 x 推入栈中。
pop() —— 删除栈顶的元素。
top() —— 获取栈顶元素。
getMin() —— 检索栈中的最小元素。

解法:建一个辅助栈,存储主栈元素对应的最小值。

  入栈:入栈元素与辅助栈的栈顶元素相比,选最小的入辅助栈

  出栈:辅助栈和主栈元素一起出栈

class MinStack:

    def __init__(self):
        """
        initialize your data structure here.
        """
        self.re = []
        self.min_stack = []

    def push(self, x: int) -> None:
        self.re.append(x)
        if not self.min_stack: 
            self.min_stack.append(x)
        else:
            self.min_stack.append(min(x,self.min_stack[-1]))

    def pop(self) -> None:
        self.re.pop()
        self.min_stack.pop()

    def top(self) -> int:
        return self.re[-1]

    def getMin(self) -> int:
        return self.min_stack[-1]


# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(x)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.getMin()

 

posted @ 2020-05-05 22:51  小xxxx程序员  阅读(283)  评论(0)    收藏  举报