Python 编程进阶经典算法逻辑编程



1. 找到数组中重复数字(字符),返回出现频次最多

字典方法,时间复杂度O(N) + O(1)

def maxf(x):
    a = dict()
    max = 0
    for i in x:
        tem = str(i)
        a[tem] = a.get(tem,0) + 1
        if max < a[tem]:
            max = a[tem]
    return max

2.二分查找

时间复杂度O(log2(N))

def find(a,b):
    min = 0
    max = len(a)-1
    if b in a:
        while True:
            centre = int((max + min)/2)
            if a[centre] > b:
                max = centre - 1
            elif a[centre] < b:
                min = centre + 1
            elif a[centre] == b:
                return centre
                break
    else:
        return('b in not in a')

3.替换字符串中空格

时间复杂度O(N)

a = input()
b = ''
for i in range(len(a)):
    if a[i] == ' ':
        b = b + 'X'
    elif a[i] != ' ':
        b = b + a[i]
print(b)

4. 斐波那契数列(跳台阶)(小矩形覆蓋大矩形)

时间复杂度O(N)

def fbnq(x):
    a = 0
    b = 1
    c = 0
    for i in range(x-1):
        c = a + b
        a = b
        b = c
    return c

递归(慢):

def fbnq(x):
    if x == 0:
        return 0
    elif x == 1:
        return 1
    elif:
        return fbnq(x-1) + fbnq(x-2)

5. 有序旋转数组最小数字查找

时间复杂度O(log2(N))

旋转数组如[1,2,3,4,5] –> [4,5,1,2,3]。二分法思想,通过比较数值不断折半搜索空间

def sortt(a,d):
    low = 0  high = len(x) - 1  while True:
        mid = int((low + high) / 2)
        if a[low] < a[mid]:
            if a[low] <= d < a[mid]:
                high = mid - 1  elif d == a[mid]:
                return mid
                break  else:
                low = mid + 1  elif a[low] == a[mid]:
            if a[low] == d:
                return low
                break  else:
                low = mid
        elif a[low] > a[mid]:
            if a[mid] < d <= a[high]:
                low = mid
            elif d == a[mid]:
                return mid
                break  else:
                high = mid - 1  return mid

6.机器人运动范围

时间复杂度O(a*b)

a*b矩阵,当a和b每位数之和sum((12,34),sum = 1+2+3+4)<=k时允许进入该格子,统计能够进入的格子个数

def counts(a,b,k):
    a = int(a)
    b = int(b)
    k = int(k)
    if k <= 0 or a <= 0 or b <= 0:
        return 0  else:
        count = 0  for x in range(1,a):
            for y in range(1,b):
                sum1, sum2, sum = 0, 0, 0  while x > 0:
                    c1 = x % 10  sum1 = sum1 + c1
                    x = int(x / 10)
                while y > 0:
                    c2 = y % 10  sum2 = sum2 + c2
                    y = int(y / 10)
                sum = sum1 + sum2
                if (sum <= k):
                    count = count + 1  return count


7.剪绳子

一根长度为n的绳子,剪成m段,n,m >1且为整数,求子段长度最大乘积。贪婪算法

def maxproduct(x):
    if x < 2:
        return 0  elif x == 2:
        return 1  elif x == 3:
        return 2  elif x == 4:
        return 4  elif x >=5:
        count = int(x/3)
        rest = x%3  if rest == 1:
            return (3**(count-1))*4  else:
            return (3**count)*rest


8.进制转换问题

时间复杂度O(log26(N))
EXCEL中,A表示第一列,AA表示低27列,根据输入字表输出是第几列
 
shuru = input()
tem = []
for i in range(len(shuru)):
    tem1 = shuru[i]
    tem2 = ord(tem1) - ord('A') + 1  tem.append(tem2)

sum = 0 tem.reverse()
for j in range(len(tem)):
    d = tem[j]*(26**j)
    sum = sum + d
print(sum)

9.二进制中1的个数

时间复杂度(log2(N))

a = input()
a = int(a)
count = 0 while a>0:
    if a%2 == 1:
        count = count + 1  a = int(a/2) (可以换成a = a>>1,此时效率更高)
print(count)


10. 一条语句判断一个整数是不是2的整数次方

一个整数如果是2的次方则二进制只有一位为1,因此如果是2的整数次方返回0

a & (a-1)


11.输入两个整数m,n,判断二进制最少改变多少位能得m->n

先求异或,再统计异或结果1的个数


12.字符串解压缩

如输入 a = ‘3[ab]acc’,则输出’abababacc’

def Ddezip(a):
    tem1 = ''  tem2 = ''  results = ''  for i in range(len(a)):
        if a[i].isdigit():
            tem1 = tem1 + a[i]
        elif a[i].isalpha():
            tem2 = tem2 + a[i]
        elif a[i] == '[':
            tem2 = ''  elif a[i] == ']':
            tem1 = int(tem1)
            for j in range(tem1):
                results = results + tem2
            tem1 = ''  tem2 = ''  if i<len(a)-1 and a[i+1].isalpha():
                for k in range(i+1,len(a)):
                    if a[k].isalpha():
                        results = results + a[k]
                    else:
                        break  return results


13.寻找所有可能子集合

输入[1,2,3],输出[[],[1],[2],[3],[1,2],[1,3],[2,3],[1,2,3]]

def FindSubset(lists):
    if len(lists) == 0:
        return [[]]
    subsets = []
    first_elt = lists[0]
    rest_list = lists[1:]
    for partial_sebset in FindSubset(rest_list):
        subsets.append(partial_sebset)
        next_subset = partial_sebset[:] + [first_elt]
        subsets.append(next_subset)
    return subsets

14. 字符串的排列
输入'abc',输出['abc', 'acb', 'bac', 'bca', 'cab', 'cba']。
 
def bianli(x):
    if len(x) <= 1:
        return x
    else:
        results = []
        for i in range(len(x)):
            for j in bianli(x[0:i]+x[i+1:]):
                results.append(x[i]+j)
        return results



15.顺时针打印长宽相等的矩阵

时间复杂度O(N*N)
a = [1,2,3,4]
x = []
for i in range(4):
    x.append(a)

l = len(x)
c = []
if l/2 ==0:
    tem = l/2
elif l/2 !=0:
    tem = int(l/2)+1

for i in range(tem):
    for j in range(i,l-i):
        c.append(x[i][j])
        tem1 = j
    for k in range(i+1,l-i):
        c.append(x[k][tem1])
        tem2 = k
    for m in range(i,l-i-1)[::-1]:
        c.append(x[tem2][m])
        tem3 = m
    for n in range(i+1,l-i-1)[::-1]:
        c.append(x[n][tem3])
print(c)

16.找到数组中出现次数超过一半的数字

[1]:建立临时变量存储数字和当前频次,时间复杂度log(N)

a = input().split()
b = [int(i) for i in a]
result = [b[0],1]
for i in range(1,len(b)):
    if result[0] == b[i]:
        result[1] = result[1] + 1
    elif result[0] != b[i]:
        result [1] = result[1] - 1
        if result[1] <= 0:
            result[0] = b[i]
            result[1] = 1
print(result[0])

[2]:堆排序建堆一波,叶子节点对应值,时间复杂度log(N)(限制,3个数时就要考虑小顶堆还是大顶堆合适)(注:建堆时间复杂度log(N),调堆时间复杂度log2(N)):

def adjust_heap(x,i,size):
    l = i*2 + 1
    r = i*2 + 2
    key = i
    if r < len(x):
        if x[l] > x[key]:
            key = l
        if x[r] > x[key]:
            key = r
        if key != i:
            x[i],x[key] = x[key],x[i]
            adjust_heap(x,key,size)

def result(x):
    size = len(x)
    for i in range(0,int(size/2))[::-1]:
        adjust_heap(x,i,size)
    return x[int(size/2)]

17.数组中连续子数组最大和

初始设置sum为0,遍历数组往后加,遇到加之后小于0情况sum清零并且result记录sum上次大于0的值。

时间复杂度O(N)

a = input().split()
b = [int(i) for i in a]
sum,result = 0,0
for i in range(len(b)):
    if sum + b[i] <= 0:
        result = sum
        sum = 0
    else:
        sum = sum + b[i]
if result > sum:
    print(result)
else:
    print(sum)

18。数字序列某一位数字

数字以123456789101112…格式序列化到一个字符序列中,求任意n位对应的数字,13位对应1

思想:前9位长度9,前99位长度2*(99-9)+9,前999位长度3*(999-99)+99

a = input()
b = int(a) 
if b <=9:
    print(n)
p = 9
lenn = 2
L = 9
i = 99
while(L<b):
    tem = L
    lenn1 = lenn
    p1 = p
    L = lenn*(i-p)+ L
    p = i
    i = i*10 + 9
    lenn = lenn+1

result = int((b-tem)/lenn1)+p1
if int((b-tem)%lenn1) == 0:
    result = result%10
else:
    chang = (b-tem)%lenn1
    tem1 = list(str(result+1))
    result = tem1[chang-1]
print(int(result))

19.找出数组中和为s的任意两数字

时间复杂度O(n*log2(n)+n)

# 堆排序或快排对a排序,时间复杂度O(N*log2(N)) def find(a,x):
    l= 0
    r = len(a)-1
    while(l < r):
        if a[l]+a[r] > x:
            r = r - 1
        if a[l]+a[r] < x:
            l = l + 1
        if a[l]+a[r] == x:
            return a[l],a[r]
            break




点赞