买卖股票的最佳时机

121. 买卖股票的最佳时机 - 力扣(LeetCode)121. 买卖股票的最佳时机 - 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。 示例 1:输入:[7,1,5,3,6,4]输出:5解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。 注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。示例 2:输入:prices = [7,6,4,3,1]输出:0解释:在这种情况下, 没有交易完成, 所以最大利润为 0。 提示: * 1 <= prices.length <= 105 * 0 <= prices[i] <= 104https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/

class Solution:
    # TLE On^2 
    def maxProfit(self, prices: List[int]) -> int:
        profit = 0
        n = len(prices)
        for i in range(n):
            for j in range(i+1,n): # 不同的日子卖
                profit = max(profit, prices[j]-prices[i])

        return profit

    # 考虑DP 
    def maxProfit(self, prices: List[int]) -> int:
        # 第j天的最大利润  = 第j天卖 - 前j天的最小值
        # dp[j] = max(dp[j-1], prices[j]-minPrice[j])
        n = len(prices)
        dp,minPrice = [0] * n,[0] * n 
        dp[0] = 0
        minPrice[0] = float('inf')

        for j in range(1,len(prices)):
            minPrice[j] = min(minPrice[j-1], prices[j-1])
            maxP = max(dp[j-1], prices[j]-minPrice[j])

        return dp[-1]
func maxProfit(prices []int) int {
    // corner case 
    n := len(prices)
    if n<=1 {
        return 0
    }

    dp := make([]int,n)
    minPrice := make([]int,n)

    dp[0] = 0
    minPrice[0] = prices[0]

    for j:=1; j<n; j++ {
        minPrice[j] = min(minPrice[j-1], prices[j])
        dp[j] = max(dp[j-1], prices[j]-minPrice[j-1])
    }
    // go 1.21 后内置max,min,clear 函数  
    ret := dp[0]
    for _,v := range dp {
        ret = max(ret,v)
    }
    // ret = max(dp[:])
    return ret
}

697. 数组的度 - 力扣(LeetCode)697. 数组的度 - 给定一个非空且只包含非负数的整数数组 nums,数组的 度 的定义是指数组里任一元素出现频数的最大值。你的任务是在 nums 中找到与 nums 拥有相同大小的度的最短连续子数组,返回其长度。 示例 1:输入:nums = [1,2,2,3,1]输出:2解释:输入数组的度是 2 ,因为元素 1 和 2 的出现频数最大,均为 2 。连续子数组里面拥有相同度的有如下所示:[1, 2, 2, 3, 1], [1, 2, 2, 3], [2, 2, 3, 1], [1, 2, 2], [2, 2, 3], [2, 2]最短连续子数组 [2, 2] 的长度为 2 ,所以返回 2 。示例 2:输入:nums = [1,2,2,3,1,4,2]输出:6解释:数组的度是 3 ,因为元素 2 重复出现 3 次。所以 [2,2,3,1,4,2] 是最短子数组,因此返回 6 。 提示: * nums.length 在 1 到 50,000 范围内。 * nums[i] 是一个在 0 到 49,999 范围内的整数。https://leetcode.cn/problems/degree-of-an-array/

func findShortestSubArray(nums []int) int {
    // 先找出nums 中的频次最大值
    freq := make(map[int]int)
    maxf := 0
    ret := math.MaxInt
    arr := map[int][]int{}
    for _,v := range(nums) {
        freq[v]+=1
        maxf = max(maxf, freq[v])
    }

    // fmt.Print(freq,maxf)
    // 找出最短的连续频次子数组
    // 子数组连续
    for k,v :=range(nums){
        if freq[v] !=maxf{
            continue
        }
        // 存储所有下标
        // if arr[v] == nil {
        //     arr[v] = []int{k} // 使用字面量初始化
        // } else {
        arr[v] = append(arr[v], k)
        // }

        if len(arr[v]) >= maxf {
            // arr[v] 中的倒数第 maxf 个元素
            ret = min(ret, 1+ k- arr[v][len(arr[v])-maxf])
        } 
    }

    return ret
}

 2012. 数组美丽值求和 - 力扣(LeetCode)2012. 数组美丽值求和 - 给你一个下标从 0 开始的整数数组 nums 。对于每个下标 i(1 <= i <= nums.length - 2),nums[i] 的 美丽值 等于: * 2,对于所有 0 <= j < i 且 i < k <= nums.length - 1 ,满足 nums[j] < nums[i] < nums[k] * 1,如果满足 nums[i - 1] < nums[i] < nums[i + 1] ,且不满足前面的条件 * 0,如果上述条件全部不满足返回符合 1 <= i <= nums.length - 2 的所有 nums[i] 的 美丽值的总和 。 示例 1:输入:nums = [1,2,3]输出:2解释:对于每个符合范围 1 <= i <= 1 的下标 i :- nums[1] 的美丽值等于 2示例 2:输入:nums = [2,4,6,4]输出:1解释:对于每个符合范围 1 <= i <= 2 的下标 i :- nums[1] 的美丽值等于 1- nums[2] 的美丽值等于 0示例 3:输入:nums = [3,2,1]输出:0解释:对于每个符合范围 1 <= i <= 1 的下标 i :- nums[1] 的美丽值等于 0 提示: * 3 <= nums.length <= 105 * 1 <= nums[i] <= 105https://leetcode.cn/problems/sum-of-beauty-in-the-array/description/

左边最大,右边最小, 结果相加时 条件1和条件2 取一个。

func sumOfBeauties(nums []int) int {
    // nums[i] 前的最大值, nums[i] 后面的最小值
    // 10^5 数据量不小 考虑下On
    n:=len(nums)
    // 默认第三种情况
    // third := make([]int,n)
    // 计算第二种情况
    second := make([]int,n)
    // 循环一下还是range , 每个下标  1<=i<=n-2  
    for i:=1;i<=n-2;i++ {
        if nums[i-1] < nums[i] && nums[i] < nums[i+1]{
            second[i] = 1 
        }
    }
    // 计算第一种情况
    first,left,right := make([]int,n),make([]int,n),make([]int,n)
    // i 左侧最大值, i 右侧最小值
    maxv,minv := math.MinInt,math.MaxInt
    left[0] = math.MinInt
    for i:=1;i<=n-2;i++ {
        maxv = max(maxv, nums[i-1])
        left[i] = maxv
    }
    right[n-1] = math.MaxInt
    for i:=n-2;i>0;i--{
        minv = min(nums[i+1],minv)
        right[i] = minv
    }
    for i:=1;i<=n-2;i++ {
        if left[i] < nums[i] && nums[i] < right[i]{
            first[i] = 2 
        }
    }
    ret := 0
    for i:=1;i<n-1;i++{
        if first[i] == 2{
            ret+= first[i]            
        } else if second[i] == 1{
            ret+= second[i]
        } 
    }

    return ret
}

122. 买卖股票的最佳时机 II - 力扣(LeetCode)122. 买卖股票的最佳时机 II - 给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。返回 你能获得的 最大 利润 。 示例 1:输入:prices = [7,1,5,3,6,4]输出:7解释:在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4。随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6 - 3 = 3。最大总利润为 4 + 3 = 7 。示例 2:输入:prices = [1,2,3,4,5]输出:4解释:在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4。最大总利润为 4 。示例 3:输入:prices = [7,6,4,3,1]输出:0解释:在这种情况下, 交易无法获得正利润,所以不参与交易可以获得最大利润,最大利润为 0。 提示: * 1 <= prices.length <= 3 * 104 * 0 <= prices[i] <= 104https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/直接遍历求利润总和, 反正也不限制买卖次数

func maxProfit(prices []int) int {
    // 可以多次买卖, 利润的和, 不限制买卖次数
    ret :=0
    for k,v := range(prices[1:]) {
        ret+= max(0, v-prices[k])
    }
    return ret
}

915. 分割数组 - 力扣(LeetCode)915. 分割数组 - 给定一个数组 nums ,将其划分为两个连续子数组 left 和 right, 使得: * left 中的每个元素都小于或等于 right 中的每个元素。 * left 和 right 都是非空的。 * left 的长度要尽可能小。在完成这样的分组后返回 left 的 长度 。用例可以保证存在这样的划分方法。 示例 1:输入:nums = [5,0,3,8,6]输出:3解释:left = [5,0,3],right = [8,6]示例 2:输入:nums = [1,1,1,0,6,12]输出:4解释:left = [1,1,1,0],right = [6,12] 提示: * 2 <= nums.length <= 105 * 0 <= nums[i] <= 106 * 可以保证至少有一种方法能够按题目所描述的那样对 nums 进行划分。https://leetcode.cn/problems/partition-array-into-disjoint-intervals/左边最大包含自己, 右边最小, 找到位置

func partitionDisjoint(nums []int) int {
    // 两次遍历,找到左边最大值, 右边最小值 kadane
    // 对每个位置,求左边的最大值小于右边的最小值, left 尽可能小,左边的第一个就是
    n:=len(nums)
    left := make([]int, n)
    right := make([]int,n)

    left[0] = nums[0] // left 包含自己
    for i:=1;i<n;i++{
        left[i] = max(left[i-1], nums[i]) 
    }
    right[n-1] = math.MaxInt
    for i:=n-2;i>=0;i--{
        right[i] = min(right[i+1],nums[i+1])
    }
    ret := 0
    for i:=0;i<=n-2;i++{
        if left[i]<=right[i]{
            ret=i+1
            break
        }
    }
    fmt.Println(left,right)
    return ret
}

2405. 子字符串的最优划分 - 力扣(LeetCode)2405. 子字符串的最优划分 - 给你一个字符串 s ,请你将该字符串划分成一个或多个 子字符串 ,并满足每个子字符串中的字符都是 唯一 的。也就是说,在单个子字符串中,字母的出现次数都不超过 一次 。满足题目要求的情况下,返回 最少 需要划分多少个子字符串。注意,划分后,原字符串中的每个字符都应该恰好属于一个子字符串。 示例 1:输入:s = "abacaba"输出:4解释:两种可行的划分方法分别是 ("a","ba","cab","a") 和 ("ab","a","ca","ba") 。可以证明最少需要划分 4 个子字符串。示例 2:输入:s = "ssssss"输出:6解释:只存在一种可行的划分方法 ("s","s","s","s","s","s") 。 提示: * 1 <= s.length <= 105 * s 仅由小写英文字母组成https://leetcode.cn/problems/optimal-partition-of-string/submissions/639077837/没遇到一个重复的就拆

func partitionString(s string) int {
    // 使用位运算bitmap
    ret := 1 
    bit := 0 
    for _,c :=range(s){
        // fmt.Print(bit)
        if (bit >> (c&31)) & 1 == 1 {
            ret++
            bit = 0
        }
        bit |= 1<<(c&31)
    }
    return ret
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值