所有题目均采用python进行完成
快速指数
求解
a
n
a^n
an
程序采用递归的思路,考虑了部分边界问题
def fast_power(a, n):
if n == 0:
return 1
elif n < 0:
return 1 / fast_power(a, -n)
elif n % 2:
return fast_power(a*a, n//2) * a
else:
return fast_power(a*a, n//2)
搜索峰值
峰值:不是最大值,比前一个和后一个大都叫峰值,我们随意返回一个即可
第一个和最后一个可以认为是负无穷大
也采用二分搜索的方法,时间复杂度为O(lgn)
注意 数组是没有排好序 也没有重复值
def search_peak(num):
return peak(num, 0, len(num)-1)
def peak(num, start, end):
if start == end:
return start
if start+1 == end:
if num[start] > num[end]:
return start
else:
return end
mid = (start + end) // 2
if num[mid] > num[mid - 1] and num[mid] > num[mid + 1]:
return mid
elif num[mid] > num[mid-1] and num[mid] < num[mid + 1]:
return peak(num, mid+1, end)
else:
return peak(num, start, mid-1)
查找第k大的值
设置一个pivot,左边的都比该数小,右边的都比该数大,我们不需要完全排序,只需要找到第k大的位置
参考:
https://blog.csdn.net/q1242027878/article/details/54925340
def find_k(num,k):
if num:
pos = partition(num, 0, len(num)-1)
if k > pos+1:
return find_k(num[pos+1:], k-pos-1)
elif k < pos+1:
return find_k(num[:pos], k)
else:
return num[pos]
def partition(nums, l, r):
low = l
while l < r:
if nums[l] > nums[r]:
nums[l], nums[low] = nums[low], nums[l]
low += 1
l += 1
nums[low], nums[r] = nums[r], nums[low]
return low
计算逆序对
输入[2,4,1,3,5]
输出 3 分别是[2,1],[4,1],[4,3]
当我们没有想法的时候,可以考虑暴力方法,找出所有对,判断是否为逆序对,时间复杂度为O(n^2),程序为:
def count_inv(num):
count = 0
for i in range(len(num)):
for j in range(i+1,len(num)):
if num[i] > num[j]:
count += 1
return count
第二种想法 采用归并排序的思路,
多了一步 判断左右两边大小的代码
代码如下
def merge(left,right):
result = []
i,j = 0,0
inv_count = 0
while i < len(left) and j < len(right):
if left[i] < right[j]:
result.append(left[i])
i += 1
elif right[j] < left[i]:
result.append(right[j])
j += 1
inv_count += (len(left)-i)
result += left[i:]
result += right[j:]
return result,inv_count
def count_inv(num):
if len(num) < 2:
return num, 0
mid = len(num) // 2
left, inv_left = count_inv(num[:mid])
right, inv_right = count_inv(num[mid:])
merged, count = merge(left, right)
count += (inv_left + inv_right)
return merged, count