算法题一:
# #第一题:两个整数数组各有100亿条数据,并已经排序,保存在磁盘上,内存10M。
# 问:
# (1)如何取得交集?时间和空间效率分别是多少?Python 集合set()操作方法
# 方法一:
# a = [2,3,4,5]
# b = [2,5,8]
# tmp = [x for x in a if x in b]
# 时间效率:两个数组长度的乘积,空间复杂度是O(1)
# 方法二:
# list(set(a).intersection(set(b)))
# (2)如果其中一个数组只有100条数据,如何优化算法取得交集?时间和空间效率分别是多少?
# 使用二分查找:
def binry_search(lst, target, start, end):
if start > end:
return False, end
mid = int((start + end)/2)
if target == lst[mid]:
return True, mid
elif target > lst[mid]:
return binry_search(lst, target, mid+1, end)
else:
return binry_search(lst, target, start, mid-1)
def get_set(lst_big, lst_small):
lst = []
start = 0
end = len(lst_big)-1
t_start = 0
t_end = len(lst_small)-1
while t_start <= t_end:
#从左边开始对小数组元素进行二分查找
exist,index = binry_search(lst_big, lst_small[t_start], start, end)
start = index
t_start += 1
if exist:
lst.append(lst_big[index])
# 从右边开始对小数组元素进行二分查找
if t_start < t_end:
exist, index = binry_search(lst_big, lst_small[t_end], start, end)
end = index
t_end -= 1
if exist:
lst.append(lst_big[index])
return lst
lst1 = list(i for i in range(100))
lst2 = [3, 5, 7, 19]
print (get_set(lst1, lst2))
"第二题:有100个磁盘组成的存储系统,当有3个磁盘同时损坏时,才会发生数据丢失。如果1个磁盘的损坏率是p,请问整个存储系统丢失数据的概率是多少?"
p=2
print((p / 100) * (p / 99) * (p / 98))
rule_list = list([str(x) for x in range(10)])
def format(char):
if not char:
return ''
if isinstance(char, int):
char = str(char)
if not isinstance(char, str):
return ''
return ''.join([x for x in char if x.isdigit()])
def send(char):
data = dict({"length": 0, "msg": ""})
char = format(char)
if char:
data["length"] = len(char)
data["msg"] = char
return data
# 11.读入一个字符串 str,输出字符串 str 中的连续最长的数字串
# 例如输入 abcd12345ed125ss123456789lk, 输出结果为123456789
def get_max_long_number(str_value):
if not isinstance(str_value, str):
return None
max_long_number = None
tmp_len = 0
for index, item in enumerate(str_value):
if item.isdigit() and index != len(str_value)-1:
tmp_len += 1
else:
if tmp_len > 0 and (max_long_number is None or tmp_len > len(max_long_number)):
max_long_number = str_value[index-tmp_len:index]
tmp_len = 0
return max_long_number
print(get_max_long_number("abcd12345ed125ss123456789a"))
# 在一个N个整数数组里面,有多个奇数和偶数,设计一个排序算法,令所有的奇数都在左边。不需要排序
lst = [2, 1, 5, 6, 7, 9, 12, 34, 13]
def sort(lst):
start = 0
end = len(lst) - 1
while start < end:
if lst[start] % 2 == 0:
while lst[end]%2 == 0:
end -= 1
# 这一步的判断一定不能少
if start < end:
lst[start], lst[end] = lst[end], lst[start]
start += 1
sort(lst)
print(lst)
# 12.翻转字符串中的单词,比如字符串 'the sky is blue' ,翻转以后是'bule is sky the'
def reverse_str(s):
if not s:
return ""
word_list = s.split()
word_list.reverse()
return " ".join(word_list)
print(reverse_str('the sky is blue'))
# 13.在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同, 则称这种编码为格雷码(Gray Code),请编写一个函数,使用递归的方法生成N位的格雷码。
# 给定一个整数n,请返回n位的格雷码,顺序为从0开始。
# 分析:
"""
1位的格雷码是 0 1
2位的格雷码是 00 01 11 10
3位的格雷码是 000 001 011 010 110 111 101 100
通过观察上面的数据,可以很快发现一些规律
(1) 2位格雷码的数量是1位的两倍,3位格雷码的数量是2位的两倍,那么照此推论,4位格雷码的数量应该是3位的两倍
(2) 2位格雷码是在1位格雷码的基础上发展来的,最高位分别加0 和 1 ,加0 生成了 00 01 加1 生成了 11 10 ,因此形成了两倍的数量差
(3) 去掉最高位后,格雷码呈现出对称的特点,比如3位格雷码,去掉最高位以后是 00 01 11 10 10 11 01 00 ,而00 01 11 10 不正是2位格雷码么,10 11 01 00 不正是2位格雷码倒过来么"""
def GrayCode(n):
if n == 1:
return ['0','1']
else:
last = GrayCode(n-1)
length = len(last)
graycode = list(i for i in range(length*2))
for i in range(length):
graycode[i] = "0" + last[i]
graycode[length+i] = "1" + last[length-i-1]
return graycode
print(GrayCode(3))
# 14.输入一个字符串,求出该字符串包含的字符集合,例如输入 “abcqweracb”,输出的结果应该是 abcqwer,要求按字符串原有的字符顺序
def get_char_set(string):
if not string:
return ""
lst = [0 for _ in range(26)]
char_lst = []
for item in string:
index = ord(item) - 97
if lst[index] == 0:
lst[index] = 1
char_lst.append(item)
return ''.join(char_lst)
print (get_char_set("abcqweracb"))
# 15.有一个数组a[N]顺序存放0~N-1,要求每隔两个数删掉一个数,到末尾时循环至开头继续进行,求最后一个被删掉的数的原始下标位置。
# 以8个数(N=7)为例:{0,1,2,3,4,5,6,7},0->1->2(删除)->3->4->5(删除)->6->7->0(删除),如此循环直到最后一个数被删除。
class Node:
def __init__(self, index):
self.pre = None
self.index = index
self.next = None
class Link:
def __init__(self, count):
self.count = count
self.head = Node(0)
self.current = self.head
for i in range(1, count):
node = Node(i)
self.current.next = node
node.pre = self.current
self.current = node
self.head.pre = self.current
self.current.next = self.head
def del_node(self, interval):
self.current = self.head
while self.count > 1:
for i in range(interval):
self.current = self.current.next
self.delete(self.current)
self.current = self.current.next
return self.current.index
def delete(self, node):
node.pre.next = node.next
node.next.pre = node.pre
self.count -= 1
link = Link(8)
print(link.del_node(2))
"""
16.风口之下,猪都能飞。当今中国股市牛市,真可谓“错过等七年”。 给你一个回顾历史的机会,已知一支股票连续n天的价格走势,以长度为n的整数数组表示,数组中第i个元素(prices[i])代表该股票第i天的股价。
假设你一开始没有股票,但有至多两次买入1股而后卖出1股的机会,并且买入前一定要先保证手上没有股票。若两次交易机会都放弃,收益为0。 设法计算你能获得的最大收益。 输入数值范围:2<=n<=100,0<=prices[i]<=100
输入:3,8,5,1,7,8, 输出:12"""
import sys
prices = [3, 8, 5, 1, 7, 8]
max = 0
#计算单个段的最大收益
def get_max(lst, start, end):
income = 0
for i in range(start, end):
for j in range(i+1, end+1):
tmp = lst[j] - lst[i]
if tmp > income:
income = tmp
return income
for i in range(1, len(prices)-1):
#分成两段去计算最大值
first = get_max(prices, 0, i)
second = get_max(prices, i+1, len(prices)-1)
income = first + second
if income > max:
max = income
print(max)
"""
17.世界上有10种人,一种懂二进制,一种不懂。那么你知道两个int32整数m和n的二进制表达,有多少个位(bit)不同么?
输入:1999 2299,输出:7
位的运算有6种:
(1) 按位与 & 相应的二进制位都为1,则该位的结果值为1,否则为0
(2) 按位或 | 相应的二进制位中只要有一个为1,该位的结果值为1
(3) 取反 ~ 一元运算符,用于求整数的二进制反码,即分别将操作数各二进制位上的1变为0,0变为1
(4) 亦或 ^ 相应的二进制位如果相同,则结果值为0,如果不相同则为1
(5) 左移 << 二进制整体左移,右边空出的位用0填补,高位左移溢出则舍弃该高位
(6) 右移 >> 右端的低位被舍弃,对于无符号数,高位补0,对于有符号数,具体补0还是1,要看系统
第4中运算,恰好符合题目的要求,就是要找到不相同的二进制位,对这两个数进行亦或运算,得到的结果就是不相同的二进制位能组成的数值,那么接下来就是计算一个整数的二进制中1的个数
"""
a = 1999
b = 2299
c = a ^ b
count = 0
while c > 0:
d = c &1
if d > 0:
count += 1
c = c >> 1
print(count)
"""
18.对于一个字符串,请设计一个高效算法,找到第一次重复出现的字符。
给定一个字符串(不一定全为字母)A及它的长度n。请返回第一个重复出现的字符。保证字符串中有重复字符,字符串的长度小于等于500。
首先要划定字符串里字符的范围,我这里划定范围是ascii码表里的字符常用的128个字符,创建一个长度为128的list,所有值设置为0
遍历每一个字符,将字符转化为10进制,以这个字符所对应的10进制值作为下角标,如果之前的值为0,则修改1,如果为1,说明在前面已经遇到过这个字符"""
string = 'q22ywyer23tdd'
lst = [0 for i in range(128)]
for ch in string:
index = ord(ch)
# if index < 65 or 91 <= index <= 96 or index > 123:
# continue
if lst[index] == 0:
lst[index] = 1
else:
print(ch)
break
posted on 2019-05-12 18:48 myworldworld 阅读(321) 评论(0) 收藏 举报