剑指Offer(Python语言)面试题11

Q1:一个m长的绳子,切两刀,分三段,组成一个三角形的概率

P=1-\frac{n+1}{2^{^{n}}}

切n刀的时候公式如上。当n=2的时候概率为1/4。


Q2:Bias?Variance?

剑指Offer(Python语言)面试题11_第1张图片

解决过拟合和欠拟合:

https://blog.csdn.net/zhuimengshaonian66/article/details/83018809


查找和排序

二分查找(折半查找)

二分查找法实质上是不断地将有序数据集进行对半分割,并检查每个分区的中间元素。在以下介绍的实现方法中,有序数据集存放在sorted中,sorted是一块连续的存储空间。参数target是要查找的数据。

此实现过程的实施是通过变量left和right控制一个循环来查找元素(其中left和right是正在查找的数据集的两个边界值)。首先,将left和right分别设置为0和size-1。在循环的每次迭代过程中,将middle设置为left和right之间区域的中间值。如果处于middle的元素比目标值小,将左索引值移动到middle后的一个元素的位置上。即下一组要搜索的区域是当前数据集的上半区。如果处于middle的元素比目标元素大,将右索引值移动到middle前一个元素的位置上。即下一组要搜索的区域是当前数据集的下半区。随着搜索的不断进行,left从左向右移,right从右向左移。一旦在middle处找到目标,查找将停止;如果没有找到目标,left和right将重合。下图显示了此过程。

代码Python语言版

def BiSearch(arr, target):
    left = 0
    right = len(arr)-1

    while left <= right:
        mid = (left + right) // 2
        if target == arr[mid]:
            return mid
        elif target > arr[mid]:
            left = mid + 1
        else:
            right = mid - 1

    return None

if __name__ == "__main__":
    arr = [10, 14, 21, 38, 45, 47, 53, 81, 87, 99]
    print(BiSearch(arr,47))

 

快速排序

快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以 递归进行,以此达到整个数据变成有序序列。

 

详解快排思想

 

核心思想:

1.在待排序的元素任取一个元素作为基准(通常选第一个元素,称为基准元素)

2.将待排序的元素进行分块,比基准元素大的元素移动到基准元素的右侧,比基准元素小的移动到作左侧,从而一趟排序过程,就可以锁定基准元素的最终位置

3.对左右两个分块重复以上步骤直到所有元素都是有序的(递归过程)

 

具体算法执行流程如下:

剑指Offer(Python语言)面试题11_第2张图片

Python语言实现:

def quick_sort(array, left, right):  
    if left >= right:  
        return  
    low = left  
    high = right  
    key = array[low]  
    while left < right:  
        while left < right and array[right] > key:  
            right -= 1  
        array[left] = array[right]  
        while left < right and array[left] <= key:  
            left += 1  
        array[right] = array[left]  
    array[right] = key  
    quick_sort(array, low, left - 1)  
    quick_sort(array, left + 1, high)
    return array


if __name__ == '__main__':
    array = [72,6,57,88,60,42,83,73,48,85]
    print(quick_sort(array, 0, len(array)-1))

算法导论书里的代码:

def quick_sort(array, l, r):
    if l < r:
        q = partition(array, l, r)
        quick_sort(array, l, q - 1)
        quick_sort(array, q + 1, r)
    return array


def partition(array, l, r):
    x = array[r]
    i = l - 1
    for j in range(l, r):
        if array[j] <= x:
            i += 1
            array[i], array[j] = array[j], array[i]
    array[i + 1], array[r] = array[r], array[i + 1]
    return i + 1


if __name__ == '__main__':
    array = [72,6,57,88,60,42,83,73,48,85]
    print(quick_sort(array, 0, len(array)-1))

面试题11:旋转数组的最小数字

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。

时间复杂度为o(n)的解决方法,从头到尾遍历数组

def minNumberInRotateArray(rotateArray):
    if not rotateArray:
        return 0
    for i in range(len(rotateArray)-1):
        if rotateArray[i] > rotateArray[i+1]:
            return rotateArray[i+1]
    return rotateArray[0]


if __name__ == "__main__":
    rotateArray = [3, 4, 5, 1, 2]
    print(minNumberInRotateArray(rotateArray))

二分查找时间复杂度为o(logn)

def Min(arr,length):
    if arr is None and length <= 0:
        return None
    index1 = 0
    index2 = length-1
    indexMid = index1
    while arr[index1] >= arr[index2]:
        if index2-index1 == 1:
            indexMid = index2
            break
        indexMid = (index1+index2)//2
        if arr[indexMid] >= arr[index1]:
            index1 = indexMid
        elif arr[indexMid] <= arr[index2]:
            index2 = indexMid

    return arr[indexMid]



if __name__ == "__main__":
    arr = [3,4,5,1,2]
    print(Min(arr,len(arr)))

 

 

 

你可能感兴趣的:(剑指offer)