天梯赛练习题

L2-002 链表去重

分数:25

考点:链表

思路:

一个标准链表题。

复杂度:O(n)

python 复制代码
import sys
input = sys.stdin.readline
l,n=map(int,input().split())
b={}
for _ in range(n):
    add,key,nexta=map(int,input().split())
    b[add]=(key,nexta)
seen=set()
keep=[]
delete=[]
p=l
while p!=-1:
    keys,nexts=b[p]
    if abs(keys) not in seen:
        seen.add(abs(keys))
        keep.append(p)
    else:
        delete.append(p)
    p=nexts
    
for i in range(len(keep)):
    addr=keep[i]
    key,_=b[addr]
    if i<len(keep)-1:
        print(f"{addr:05d} {key} {keep[i+1]:05d}")
    else:
        print(f"{addr:05d} {key} -1")

for i in range(len(delete)):
    addr=delete[i]
    key,_=b[addr]
    if i<len(delete)-1:
        print(f"{addr:05d} {key} {delete[i+1]:05d}")
    else:
        print(f"{addr:05d} {key} -1")

L2-004 这是二叉搜索树吗?

分数:25

考点:二叉树

思路:

先序遍历是根左右,后序遍历是左右根,也就是说我们递归判断的时候可以先递归左边,再递归右边,最后把根加入答案。这样就正好得到后序遍历了。

复杂度:O()

python 复制代码
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10000)
n=int(input())
a=list(map(int,input().split()))
post=[]
def check(l,r):
    if l>r:
        return True
    p=a[l]
    k=l+1
    while k<=r and a[k]<p:
        k+=1
    for i in range(k,r+1):
        if a[i]<p:
            return False
    if not check(l+1,k-1):
        return False
    if not check(k,r):
        return False
    post.append(p)
    return True

def check2(l,r):
    if l>r:
        return True
    p=a[l]
    k=l+1
    while k<=r and a[k]>=p:
        k+=1
    for i in range(k,r+1):
        if a[i]>=p:
            return False
    if not check2(l+1,k-1):
        return False
    if not check2(k,r):
        return False
    post.append(p)
    return True
if check(0,n-1):
    print("YES")
    print(*post)
else:
    post=[]
    if check2(0,n-1):
        print("YES")
        print(*post)
    else:
        print("NO")

L2-005 集合相似度

分数:25

考点:模拟

思路:

先将每个组的数字集合去重,然后对要选的两个集合取交集和并集,最后用交集除以并集输出结果即可。

复杂度:O(n)

python 复制代码
import sys
import heapq
input = sys.stdin.readline
n=int(input())
a=[]
for _ in range(n):
    b=list(map(int,input().split()))
    b=set(b[1:])
    a.append(b)
q=int(input())
for _ in range(q):
    l,r=map(int,input().split())
    l-=1
    r-=1
    c=len(a[l]&a[r])#取交集
    d=len(a[l]|a[r])#取并集
    print(f"{c/d*100:.2f}%")

L2-006 树的遍历

分数:25

考点:bfs,二叉树

思路:

先通过后序遍历的最后一位确定根的值,然后再看这个值在中序遍历的位置,这个值的左边就是左子树,右边就是右子树。(因为先序是根左右,中序是左根右,后序是左右根)

找出先序后,再用dfs按层输出即可。

复杂度:O()

python 复制代码
import sys
import heapq
from collections import deque
input = sys.stdin.readline
n=int(input())
a=list(map(int,input().split()))
b=list(map(int,input().split()))
def dg(a,b):
    if not a:
        return []
    root=a[-1]
    k=b.index(root)
    left=b[:k]
    right=b[k+1:]

    len_l=len(left)

    left_p=a[:len_l]
    right_p=a[len_l:-1]

    return [root,dg(left_p,left),dg(right_p,right)]
root=dg(a,b)
q=deque([root])
ans=[]
while q:
    node=q.popleft()
    if node is None:
        continue
    ans.append(node[0])
    if node[1]:
        q.append(node[1])
    if node[2]:
        q.append(node[2])
print(*ans)

L2-008 最长对称子串

分数:25

考点:回文串

思路:

求一个字符中最长的回文串长度,就是固定一个中心点,然后将他左右两边移动看是否相等,并每次进行计数。

可以分为两类:

  • 子串长度是奇数情况下,两点都在一起。
  • 子串长度为偶数情况下,两点再子串中心的那两个点处。

复杂度:O(n)

python 复制代码
import sys
import heapq
from collections import deque
input = sys.stdin.readline
a=input().strip()
n=len(a)
def pd(l,r):
    while l>=0 and r<n and a[l]==a[r]:
        l-=1
        r+=1
    return r-l-1
ans=0
for i in range(n):
    ans=max(ans,pd(i,i))
    ans=max(ans,pd(i,i+1))
print(ans)

L2-011 玩转二叉树

分数:25

考点:二叉树,递归

思路:

这题跟上文那个L2-006的唯一区别就是要在递归的时候把两个参数位置调换一下,实现题目要求的反转需要即可。

复杂度:O()

python 复制代码
import sys
input = sys.stdin.readline
from collections import deque
n=int(input())
a=list(map(int,input().split()))
b=list(map(int,input().split()))
def dg(a,b):
    if not b:
        return None
    root=b[0]
    k=a.index(root)
    left=a[:k]
    right=a[k+1:]
    len_l=len(left)
    left_p=b[1:1+len_l]
    right_p=b[1+len_l:]
    return [root,dg(right,right_p),dg(left,left_p)]
root=dg(a,b)
q=deque([root])
ans=[]
while q:
    node=q.popleft()
    if node is None:
        continue
    ans.append(node[0])
    if node[1]:
        q.append(node[1])
    if node[2]:
        q.append(node[2])
print(*ans)

L2-012 关于堆的判断

分数:25

考点:小顶堆

思路:

先把给定的一串数字,按顺序一个一个插入到小顶堆里。插完以后堆的形状就确定了。然后再去判断后面给出的每一句话对不对。

复杂度:

python 复制代码
import sys
input = sys.stdin.readline
from collections import deque
n,m=map(int,input().split())
a=list(map(int,input().split()))
#手动插入,建立小顶堆
heap=[0]
for x in a:
    heap.append(x)
    i=len(heap)-1
    while i>1 and heap[i]<heap[i//2]:
        heap[i],heap[i//2]=heap[i//2],heap[i]
        i//=2
#记录每个值在堆中的位置
pos={}
for i in range(1,len(heap)):
    pos[heap[i]]=i
#判断命题
for _ in range(m):
    s=input().strip()
    words=s.split()
    if "root" in s:
        x=int(words[0])
        print("T" if heap[1]==x else "F")
    elif "siblings" in s:
        x=int(words[0])
        y=int(words[2])
        print("T" if pos[x] // 2 == pos[y] // 2 else "F")
    elif "parent" in s:
        x = int(words[0])
        y = int(words[-1])
        print("T" if pos[y] // 2 == pos[x] else "F")

    elif "child" in s:
        x = int(words[0])
        y = int(words[-1])
        print("T" if pos[x] // 2 == pos[y] else "F")
    
相关推荐
weixin_421922692 小时前
分布式日志系统实现
开发语言·c++·算法
阿钱真强道2 小时前
26 Python 分类:一个模型不够稳怎么办?一文认识组合分类
python·随机森林·分类·提升·组合分类·装袋·投票分类器
不想看见4042 小时前
Daily Temperatures单调栈--力扣101算法题解笔记
算法
左左右右左右摇晃2 小时前
Java笔记——多态
java·笔记·python
炽烈小老头2 小时前
【每天学习一点算法 2026/03/21】颜色分类
学习·算法
爱编程的小吴2 小时前
LangChain基础入门:DocumentLoader加载PDF/Markdown文档实战
python·langchain·pdf
灰色小旋风2 小时前
力扣17 电话号码的字母组合(C++)
c++·算法·leetcode
无敌憨憨大王2 小时前
并查集(图论)
数据结构·算法·图论
xiaoye-duck2 小时前
《算法题讲解指南:动态规划算法--路径问题》--7.礼物的最大价值,8.下降路径最小和
c++·算法·动态规划