牛客ACM刷题记录——开篇

写在前面,打算好好锻炼一下手撕的能力,之前 leetcode 也刷了挺多的,但是笔试基本都是 ACM 模式,有时候测试样例过了,但是通过率 0%很是头疼。于是希望通过ACM 模式,看是否能改善一点。

在这里插入图片描述

这里附上代码联系地址:牛客 ACM 刷题地址

牛客的 ACM 模式很多都没看到 python 的题解,所以自己打算边写边思索下。

Day 1:6 月 6 日

最长上升子序列

题目地址

在这里插入图片描述

第一版提交,没过:

n = int(input())
nums = list(map(int, input().split()))

max_ = 1
cur = 1
dp = [1] * n

for i in range(1, n):
    for j in range(i):
        if nums[i] > nums[j]:
            dp[i] = max(dp[i], dp[j] + 1)
    max_ = max(max_, dp[i])
    
print(max_)

(PS: 有一说一,提交一次挺久的,几十秒了)

中午或者下班再看看吧,不知道哪里错了😭

超时了估计

在这里插入图片描述


吃完晚饭,在跑代码的时候抽空想想……

不知道哪里有问题,交给 gpt 了,a 了……(这让人无语😅)

下面是 chtgpt4o 生成的,可以直接提交,看看人工智能的思路:

def length_of_lis(nums):
    from bisect import bisect_left
    
    if not nums:
        return 0
    
    dp = []
    for num in nums:
        pos = bisect_left(dp, num)
        if pos < len(dp):
            dp[pos] = num
        else:
            dp.append(num)
    
    return len(dp)

# 读取输入
n = int(input().strip())
nums = list(map(int, input().strip().split()))

# 输出结果
print(length_of_lis(nums))

~~思路是这样的🤔

在这里插入图片描述
思路是来看就是遍历,维护一个严格递增的子序列;

按递增顺序添加末尾好理解,比较难 get 的是用二分查找去替换;
其实用小的把 dp 数组里面的大的去替换,可以理解为将 dp 数组做了一个 压紧操作(想象是一个弹簧)

比如序列是 1,2,7,5,6
那么一开始按顺序添加会得到【1、2、 7】

这个时候查找 5,对应做替换的是 7,因为 2 和 7 之间有太多空气,所以让 5 替换 7,做了压紧
这样给了我们更多机会去把相对较大的数字给放进来(指的是 5<n<7的这些数字),所以能够保证数字是尽可能按规则往里面放的
-> 最后放入 6,返回长度 4

个人感觉那一步有点贪心的意思,动态规划没太感觉到。🤔


另外顺便学一下二分查找的懒人用法 bisect_left

这个是需要导入包的,bisect_left返回大于等于x的第一个下标

from bisect import bisect_left
index1 = bisect(List, x)   #第1个参数是列表,第2个参数是要查找的数,返回值为索引

当然,我们真正手撕其实不太可能用这么偷懒的,毕竟一个二分操作的难度都可以手撕了,怎么可能放过你,下面附上那么精简的代码:

"""20240606 第二版"""    

# 二分查找 Index
def Bisect(arr, n):
    left, right = 0, len(arr) - 1
    while left <= right:
        mid = (left + right) // 2

        if arr[mid] == n:
            return mid
        elif arr[mid] < n:
            left = mid + 1
        else:
            right = mid - 1
        
    return left

n = int(input())
nums = list(map(int, input().split()))
if len(nums) == 0:
    print(0)

else:
    dp = []
    for i in range(n):
        pos = Bisect(dp, nums[i])
        if pos < len(dp):
            dp[pos] = nums[i]
        else:
            dp.append(nums[i])
#         print(dp)
    print(len(dp))
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值