IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> leetcode:1713.得到子序列的最少操作次数 -> 正文阅读

[数据结构与算法]leetcode:1713.得到子序列的最少操作次数

?solution1:

????????最开始的想法,递归,for循环target,如果arr里面没有则加1,如果有递归,两种情况。1、插入新的target为[1,3],新的arr为匹配到的位置后面的部分[9,4,1,2,3,4],这里还有一个细节,就是有可能arr有相同的数。2、不插入,加1,新的target[1,3],arr保持不变。然后对两种结果取最小值

count =0
clist =[]
def compc(target,arr,count):
    for i in range(len(target)):
        num = target[i]
        loc = np.where(arr==num)
        if(len(loc[0]) ==0):
            count = count+1
        else:
            if(i==len(target)-1):
                return count
            clistt = []
            countb = compc(target[i + 1:], arr, count + 1)
            clistt.append(countb)
            for j in range(len(loc[0])):
                a = int(loc[0][j])
                arrt = arr[a:]
                counta = compc(target[i+1:], arrt,count)
                clistt.append(counta)
            count= min(clistt)
            clist.append(count)
            return count
    return count
c = compc(target,arr,count)
print(clist)
if len(clist)>1:
    c = min(clist)
print(c)

很显然,空间复杂度和时间复杂度严重超标。

?solution2:

? ? ? ? 看了一眼解析,哦,找最长公共子序列,那就动态规划,就去看了一眼动态规划的逻辑,直接暴力复现

? ? ? ? 这块的关键是转换了思想,在arr里寻找包含的target里的元素以及对应的位置,我感觉我下次还是想不到。。。。

#转换为最长递增子序列,暴力动态规划
pos =[]
tmp =0
for i in range(len(arr)):
    if arr[i] in target:
        al = np.where(target==arr[i])
        pos.append(al[0])
dp = np.ones(len(pos))
for i in range(len(pos)):
    val = pos[i]
    for j in range(i):
        if(pos[j]<val):
            dp[i]=max(dp[i],dp[j]+1)
c =len(target) -int(max(dp))
print(c)

很显然还是超时。

?solution3:

? ? ? ? 这时,target的特点就要突出了,递增序列,意味着寻找递增的子序列,那么第二层for循环就可以简化了,这个逻辑,pos里面的元素可以通过对比大小来进行删除,将for循环换成了while(这里用了二分法来插入)

#二分法 动态规划
pos =[]
for i in range(len(arr)):
    if arr[i] in target:
        al = np.where(target==arr[i])
        pos.append(al[0])
dp = []
dp.append(pos[0])
tmp =1
for i in range(1,len(pos)):
    if(dp[len(dp)-1]<pos[i]):
        dp.append(pos[i])
    else:
        l=0
        r = len(dp)-1
        loc =r
        while(l<=r):
            mid = (l+r)//2
            if(dp[mid]>=pos[i]):
                loc = mid
                r = mid-1
            else:
                l = mid+1
        dp[loc] =pos[i]
c =len(target) -len(dp)
print(c)

?发现还是超时,,emmm,又看了一眼解析,发现一个for循环和第二个for循环完全可以合并啊,用了bisect.bisect_left二分查找的库,我寻思库能比我写的快点?然后又又又试了一下

?solution4:

#两个for循环可以合并
pos = []
dp = []
for i in range(len(arr)):
    if arr[i] in target:
        al = np.where(target == arr[i])
        # pos.append(al[0])
        idx = al[0]
        if (len(dp) == 0 or idx > dp[len(dp) - 1]):
            dp.append(idx)
        else:
            site = bisect.bisect_left(dp, idx)
            if site < len(dp):
                dp[site] = idx
            else:
                dp.append(idx)
c = len(target) - len(dp)

????????还是不行,还是超时,然后我把答案里面的c++版本拷进去提交了一下,是真的快,应该是python本身的局限性吧。看起来逻辑是一样的,行吧,思想最重要,就到这吧。

学了忘,忘了学,学了还得忘,忘了学,学了忘,忘了还得学。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-08-08 11:34:33  更:2021-08-08 11:51:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 18:36:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码