MOOC数据结构与算法Python版-第四周编程作业

1 有序队列(10分)

题目内容:

一开始给出了一个由小写字母组成的字符串 S。我们规定每次移动中,选择最左侧的字母,将其从原位置移除,并加到字符串的末尾。这样的移动可以执行任意多次

返回我们移动之后可以拥有的最小字符串(注:在Python3中,字符串的大小可用不等号比较)。

 

输入格式:

S。S为仅含有小写字母的字符串,长度不超过100000。

 

输出格式:

一个与S等长的字符串。

 

输入样例:

"cba"

 

输出样例:

acb

 

代码模板(建议复制粘贴使用):

 

  1. def func(S):
  2.     # your code here
  3.     return output
  4.      
  5. S = eval(input())
  6. print(func(S))

 

时间限制:500ms内存限制:32000kb

解题思思路1:

应用队列的先进先出特点,设置最开始的字符串为最小值,不断的将最后一个字母出队列,然后再将这个字母入队列,与设置的字符串进行比较,若小于的话,则替换最小值,若大于的话,继续出队列、入队列。直到将字符串的所有情况都遍历一遍。

程序代码1:

class Queue:
    def __init__(self):
        self.items = []

    def isEmpty(self):
        return self.items == []

    def enqueue(self, item):
        self.items.insert(0,item)

    def dequeue(self):
        return self.items.pop()

    def size(self):
        return len(self.items)


def func(S):
    q = Queue()
    min_str = S
    temp = 0
    for i in S:
        q.enqueue(i)
    while(temp<=q.size()):
        first = q.dequeue()
        q.enqueue(first)
        new_list = ''.join(q.items)[::-1]
        if new_list < min_str:
            min_str = new_list
        temp = temp + 1
    print(min_str)

解题思路2: 

利用对字符串切片处理,直接将最后一个字母拼接到后面,然后进行比较得最小字符串。

程序代码2 :

def func(S):
    min_str = S
    for i in range(len(S)):
        S = S[1:] + S[0]
        if S < min_str:
            min_str = S
    return min_str
S = eval(input())
print(func(S))

2 最近的请求次数(10分)

题目内容:

计算每个事件发生之时,往前算10000毫秒内有多少个事件发生,包含当事件;也即对于列表中的每个元素k,算出整个列表中有多少个元素介于k-10000和k(两端均含)之间。

 

输入格式:

一个已排序列表mylist,所有元素为非负整数,记录各个请求的发生时间,单位为毫秒。

 

输出格式:

一个与mylist等长的列表。

 

输入样例:

[0,10,100,1000,10000,20000,100000]

 

输出样例:

[1,2,3,4,5,2,1]

 

代码模板(建议复制粘贴使用)

 

  1. def func(mylist):
  2.     # your code here
  3.     return output
  4.      
  5. mylist = eval(input())
  6. print(func(mylist))

 

时间限制:500ms内存限制:32000kb

解题思路:

应用队列先进先出的特点,先入队第一个元素进行计算,然后再加新的元素入队,同时循环判断队列首元素减去队尾元素是否大于10000,若大于的话,将队尾元素删除,否则返回队列的长度即为处于范围之间的元素个数。

这里一定要注意的是,已排序列表中可能会有相同的值,所以需要一个计数器来记录,重复值出现了几次。

程序代码:


class Queue:
    def __init__(self):
        self.items = []

    def isEmpty(self):
        return self.items == []

    def enqueue(self, item):
        self.items.insert(0,item)

    def dequeue(self):
        return self.items.pop()

    def size(self):
        return len(self.items)

def func(mylist):
    new_list = []
    output = []
    temp = 0
    q = Queue()
    for i in mylist:
        q.enqueue(i)
    # print(q.items)
    while(temp<len(mylist)):
        first = q.dequeue()
        new_list.append(first)

        while new_list[-1] - new_list[0] > 10000:
            new_list.pop(0)
        sum = 0
        for i in reversed(q.items):
            if i == new_list[-1]:
                sum = sum + 1
            else:
                break
        if sum != 0:
            output.append(len(new_list)+sum)
        else:
            output.append(len(new_list))
        temp = temp + 1
    print(output)

mylist = eval(input())
func(mylist)


3 基数排序(10分)

题目内容:

实现一个基数排序算法,用于10进制的正整数从小到大的排序。

思路是保持10个队列(队列0、队列1......队列9、队列main),开始,所有的数都在main队列,没有排序。

第一趟将所有的数根据其10进制个位(0~9),放入相应的队列0~9,全放好后,按照FIFO的顺序,将每个队列的数合并排到main队列。

第二趟再从main队列队首取数,根据其十位的数值,放入相应队列0~9,全放好后,仍然按照FIFO的顺序,将每个队列的数合并排到main队列。

第三趟放百位,再合并;第四趟放千位,再合并。

直到最多的位数放完,合并完,这样main队列里就是排好序的数列了。

 

输入格式:

一个列表mylist,其中mylist包含一些需要排序的正整数,正整数互不相同且均不超过100000,且个数在1至1000之间。

 

输出格式:

一个与mylist等长的列表。

 

输入样例:

[8, 91, 34, 22, 65, 30, 4, 55, 18]

 

输出样例:

[4, 8, 18, 22, 30, 34, 55, 65, 91]

 

代码模板(建议复制粘贴使用)

 

  1. def func(mylist):
  2.     # your code here
  3.     return output
  4.      
  5. mylist = eval(input())
  6. print(func(mylist))

 

 

时间限制:500ms内存限制:32000kb

解题思路:

基数排序是八大排序中的一种,排序过程如下:

上述中有一串数值为:3 44 38 5 47 15 36 26 27 2 46 4 19 50 48

首先根据个位数的数值,在走访数值时将它们分配至编号0到9的桶子中:

0 :50

1:

2:2

3:3

4:44  4

5:5  15

6:36  26  46

7:47  27

8:38 48

9:19

第二步
接下来将这些桶子中的数值重新串接起来,成为以下的数列:

50 2 3 44 4 5 15 36 26 46 47 27 38 48 19

接着再进行一次分配,这次是根据十位数来分配:

0:2 3 4 5

1:15 19

2:26 27

3:36 38

4:44 46 47 48 

5:50

6:

7:

8:

9:

第三步
接下来将这些桶子中的数值重新串接起来,成为以下的数列:

2 3 4 5 15 19 26 27 36 38 44 46 47 48 50

这时候已经排序完成,如果最高位是3位数或者更多,则继续进行上面直到高位数排完为止。

时间效率 :设待排序列为n个记录,d个关键码,关键码的取值范围为radix,则进行链式基数排序的时间复杂度为O(d(n+radix)),其中,一趟分配时间复杂度为O(n),一趟收集时间复杂度为O(radix),共进行d趟分配和收集。 空间效率:需要2*radix个指向队列的辅助空间,以及用于静态链表的n个指针。

程序代码:

def RadixSort(mylist):
    i = 0                                             #初始为个位排序
    n = 1                                           #最小的位数置为1(包含0)
    max_num = max(mylist)                       #得到带排序数组中最大数
    while max_num >= 10**n:              #得到最大数是几位数
        n += 1
    while i < n:
        bucket = {}                             #用字典构建桶
        for x in range(10):
            bucket.setdefault(x, [])    #将每个桶置空
        for x in mylist:                               #对每一位进行排序
            radix =int((x / (10**i)) % 10)   #得到每位的基数
            bucket[radix].append(x) #将对应的数组元素加入到相应位基数的桶中
        j = 0
        for k in range(10):
            if len(bucket[k]) != 0:       #若桶不为空
                for y in bucket[k]:         #将该桶中每个元素
                    mylist[j] = y                       #放回到数组中
                    j += 1
        i += 1

if __name__ == '__main__':
    mylist = eval(input())
    RadixSort(mylist)
    print(mylist)

 

 

  • 12
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

suxiaorui

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值