别扭的一天

300. 最长上升子序列

题目:给定一个无序的整数数组,找到其中最长上升子序列的长度
示例:
输入:[10,9,2,5,3,7,101,18]
输出:4
解释:最长的上升子序列是[2,3,7,101]。

思路:动态规划
dp[i]表示以当前元素结尾的子序列的最长长度。
dp[i] = max(dp[j]) + 1 (nums[i] > nums[j])

class Solution(object):
    def lengthOfLIS(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if not nums:
            return 0
        dp = []
        for i in range(len(nums)):
            if i == 0:
                dp.append(1)
            else:
                t = 0
                #找到前面比当前元素小,且长度最长的元素
                for j in range(i):
                    if nums[j] < nums[i] and dp[j] > t:
                        t = dp[j]
               	#将当前元素加入到找到的元素后面,长度加1
                dp.append(t+1)
        return max(dp)

优化:排序 + 二分算法
在找前面比当前元素小且长度最长的子序列时,可以通过结合排序列表,二分查找来提升效率。

面试题01.07 旋转矩阵

给定一幅由N*N矩阵表示的图像,编写一种方法,将图像旋转90度。
不占用额外内存空间能否做到?
示例:
给定 matrix 为左边,原地旋转输入矩阵,使其变为右边:

始:[[1,2,3],           终:[[7,4,1],
    [4,5,6],	        	[8,5,2],
    [7,8,9]]				[9,6,3]]

思路:绕圈旋转
首先,确定旋转的圈数为N/2,即可将矩阵分为N/2圈。
其次,确定每一圈旋转的次数为该圈的边长减1。
每次旋转的时候将四个元素互换位置即可。
每次旋转的四个元素为四个角向对应方向移动j位。

class Solution(object):
    def rotate(self, matrix):
        """
        :type matrix: List[List[int]]
        :rtype: None Do not return anything, modify matrix in-place instead.
        """
        length = len(matrix) - 1
        i = 0
        while i < len(matrix)/2:
            for j in range(length):
                matrix[i][i+j], matrix[i+j][i+length],matrix[i+length][i+length-j], matrix[i+length-j][i] = matrix[i+length-j][i],matrix[i][i+j], matrix[i+j][i+length],matrix[i+length][i+length-j]
            length -= 2
            i += 1
            

面试题16.26 计算器

给定一个包含正整数、加、减、乘、除的算术表达式(括号除外),计算其结果。
表达式仅包含非负整数,+, -, *, /四种运算符和空格 。整数出发仅保留整数部分。

思路:
初始lis =[],存储操作数;初始stack1=[],存储整数;初始stack2=[],存储运算符;
1.整理字符串,将字符串中的整数和运算符部分挑出来,并将整数转换成int类型。
2.用栈来模拟运算先算乘除,再算加减。
扫描列表,遇到整数进栈stack1,遇到乘或除号,将stack1栈顶出栈与下一个整数运算,然后进栈stack1。
需要注意的是,计算加减时要从左到右运算,即应该从stack1栈底向上扫描。

class Solution(object):
    def calculate(self, s):
        """
        :type s: str
        :rtype: int
        """
        multi_1 = ['+','-']
        multi_2 = ['*','/']
        lis = []
        i = 0
        while i < len(s):
            t = i
            while '0' <= s[i] <= '9' and i < len(s)-1:
                i += 1
            if s[t] != ' ':
                if s[t] in multi_2 + multi_1:
                    lis.append(s[t])
                else:
                    if '0' <= s[i] <= '9' and i != t:
                        lis.append(s[t:i+1])
                        break
                    else:
                        if i != t:
                            lis.append(s[t:i])
                        if s[i] != ' ':
                            lis.append(s[i])
            i += 1

        for i in range(len(lis)):
            if lis[i] not in multi_2 + multi_1:
                lis[i] = int(lis[i])


        stack_1 = []
        stack_2 = []
        i = 0
        while i < len(lis):
            if lis[i] != '' and lis[i] not in multi_1 + multi_2:
                stack_1.append(lis[i])
            if lis[i] in multi_1:
                stack_2.append(lis[i])
            if lis[i] in multi_2:
                if lis[i] == '*':
                    x = stack_1.pop()
                    x *= lis[i+1]
                    stack_1.append(x)
                if lis[i] == '/':
                    x = stack_1.pop()
                    x /= lis[i+1]
                    stack_1.append(x)
                i += 1
            i += 1
        stack_1 = stack_1[::-1]
        stack_2 = stack_2[::-1]
        while len(stack_1) > 1:
            z = stack_2.pop()
            x = stack_1.pop()
            y = stack_1.pop()
            if z == '+':
                stack_1.append(x+y)
            if z == '-':
                stack_1.append(x-y)
        return stack_1[0]

面试题08.11 硬币

硬币。给定数量不限的硬币,币值为25分、10分、5分和1分,编写代码计算n分有几种表示法。结果模上10**9+7。
示例:
输入: n = 5
输出:2
解释:5 = 5, 5 = 1 + 1 + 1 + 1 + 1;这两种表示法。

思路:二维动态规划
这里硬币分为4种,coins = [1, 5, 10, 25]
分四遍扫描,每一遍代表当前n分由前i中表示的方法数目。
dp[j]表示,j分由前i种硬币表示的方法数。
dp[j] += dp[j-coins[i]]

class Solution(object):
    def waysToChange(self, n):
        """
        :type n: int
        :rtype: int
        """
        lis = []
        coins = [1,5,10,25]
        #前两轮分别表示,只由1分和由1分、五分的表示方法
        for i in range(n+1):
            lis.append(1 + i/5)
        for i in range(2,4):
            for j in range(n+1):
                if j >= coins[i]:
                    lis[j] += lis[j-coins[i]]
        return lis[-1] % (10**9+7)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值