算法-刷题

一、双指针

题目1: 题目描述:在有序数组中找出两个数,使它们的和为 target

def twosum(number,target):
    i = 0
    j = len(number)-1
    if j <= 0:
        return '只有一个数'
    while i<j :
        sum1 = number[i] + number[j]
        if sum1 == target:
            a = [i+1,j+1]
            return a 
        elif sum1 < target:
            i=i+1
        else :
            j=j-1
    return '没有数据'
number1 = [2,9,54,72]
target1 = 63
a = twosum(number1,target1)
#[2, 3] 

题目2:两数平方和。题目描述:题目描述:判断一个非负整数是否为两个整数的平方和。

def judgeSquareSum(target):
    i = 0
#     j = round(sqrt(target))
    j = round(target/2) #由于没有sqrt函数,因此使用处以2,但是这种情况会有小于4的数会有问题。
    if target < 0 :
        return '非法值'
    while i<j:
        sum1 = i*i + j*j
        if sum1 == target:
            return [i,j]
        elif sum1 < target:
            i=i+1
        else:
            j=j-1
    return '无法找到'
target1 = 48
a = judgeSquareSum(target1)

#方法2:
import math as mt
def judgesumsquare(tar):
    i = 0
    # 对target开方后的到的最大整数
    j = int(mt.sqrt(tar))
    while i <= j:
        # 如果i和j的平方和等于targer,则返回true
        if i** 2 + j**2 == tar:
            return True
        # 如果i和j的平方和小于targer,则放大i
        elif i**2 + j**2 < tar:
            i = i + 1
        # 否则,则缩小j
        else:
            j = j - 1
    return False

题目3:反转字符串中的元音字符。当两个指针都遍历到元音字符时,交换这两个元音字符。

def reverseVowels(t):
    a = ['a','e','i','o','u','A','E','I','O','U']
    s = []
#     for m in t:  #方法1:用for循环append进list中
#         s.append(m)
    s = list(t)  #方法2:直接用list()函数强制转换str类型为list
    i = 0
    j = len(s)-1
    while i < j:
        if s[i] not in a:
            i += 1
        elif s[j] not in a:
            j -= 1
        else:
            s[i],s[j] = s[j],s[i]
            i += 1
            j -= 1
    r = "".join(s) #将list转换成str输出
    return r
s1 = 'leetcode'
m = reverseVowels(s1)

题目4:回文字符串。可以删除一个字符,判断是否能构成回文字符串。

def isPalindrome(s,i,j):
    while i<j:
        if s[i] != s[j]:
            return False
        else:
            i += 1
            j -= 1
    return True


def validPalindrome(s):
    s = list(s)
    i = 0
    j = len(s) - 1
    while i < j:
        if s[i] != s[j]:
            return isPalindrome(s,i,j-1) or isPalindrome(s,i+1,j)
        else:
            i = i+1
            j = j-1
    return True 
m = validPalindrome('adbcdba')

题目5:两个数组合并

def merge_sort(nums1, nums2):
    m = []
    i, j = 0, 0
    l_1, l_2 = len(nums1)-1, len(nums2)-1
    # 当i,j的索引位置小于等于索引最大值的时候
    while i <= l_1 and j <= l_2:
        if nums1[i] <= nums2[j]:
            m.append(nums1[i])
            i += 1
        else:
            m.append(nums2[j])
            j += 1
    m = m + nums1[i:] + nums2[j:]
    return m
if __name__ == '__main__':
    n1 = [1, 2, 3, 5]
    n2 = [2, 4, 5, 7]
    m = merge_sort(n1, n2)
    print(m)

题目6:判断链表是否存在环。使用双指针,一个指针每次移动一个节点,一个指针每次移动两个节点,如果存在环,那么这两个指针一定会相遇。

class Node(): #定义一个Node类,构造两个属性,一个是item节点值,一个是节点的下一个指向
    def __init__(self,item=None):
        self.item = item
        self.next = None
 
def findbeginofloop(head):#判断是否为环结构并且查找环结构的入口节点
    slowPtr = head         #将头节点赋予slowPtr
    fastPtr = head         #将头节点赋予fastPtr
    loopExist =False       #默认环不存在,为False
    if head == None:       #如果头节点就是空的,那肯定就不存在环结构
        return False
    while fastPtr.next != None and fastPtr.next.next != None:      #fastPtr的下一个节点和下下个节点都不为空
        slowPtr = slowPtr.next           #slowPtr每次移动一个节点
        fastPtr = fastPtr.next.next      #fastPtr每次移动两个节点 
        if slowPtr == fastPtr :          #当fastPtr和slowPtr的节点相同时,也就是两个指针相遇了
            loopExist = True
            print("存在环结构")
            break
 
    if loopExist == True:  
        """寻找环的入口,在找到第一次相遇后,
        使一个指针指向头,另一个指针在相遇处,
        然后两个指针每次移动一步,相遇时所指即为环入口"""
        slowPtr  = head
        while slowPtr != fastPtr:
            fastPtr = fastPtr.next
            slowPtr = slowPtr.next
        return slowPtr
 
    print("不是环结构")
    return False
    
if __name__ == "__main__":
    node1 = Node(1)
    node2 = Node(2)
    node3 = Node(3)
    node4 = Node(4)
    node5 = Node(5)     
    node1.next = node2
    node2.next = node3
    node3.next = node4
    node4.next = node5
    node5.next = node2
    print(findbeginofloop(node1).item)

题目7:最长子序列。题目描述:删除 s 中的一些字符,使得它构成字符串列表 d 中的一个字符串,找出能构成的最长字符串。如果有多个相同长度的结果,返回字典序的最小字符串。

def issubstr(s,t): #判断是否为子序列
    i = 0
    j = 0
#     s = list(s)
#     t = list(t)
    while i <= len(s)-1 and j < len(t)-1:
        if s[i] == t[j]:
            j += 1
        i += 1
    return j == len(t)

二、排序

2.1 冒泡排序

def bubbleSort(arr):
    n = len(arr)
    # 遍历所有数组元素
    for i in range(n):
        for j in range(0, n-i-1):
            if arr[j] > arr[j+1] :
                arr[j], arr[j+1] = arr[j+1], arr[j]
 
arr = [64, 34, 25, 12, 22, 11, 90]
bubbleSort(arr)

2.2 快速排序

# 从数列中挑出一个元素,称为 "基准"(pivot);
# 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
# 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;

def partition(arr,low,high): 
    i = ( low-1 )         # 最小元素索引
    pivot = arr[high]     
  
    for j in range(low , high): 
        # 当前元素小于或等于 pivot 
        if  arr[j] <= pivot: 
            i = i+1 
            arr[i],arr[j] = arr[j],arr[i] 
    arr[i+1],arr[high] = arr[high],arr[i+1] 
    return ( i+1 ) 

# arr[] --> 排序数组
# low  --> 起始索引
# high  --> 结束索引
  
# 快速排序函数
def quickSort(arr,low,high): 
    if low < high: 
  
        pi = partition(arr,low,high) 
  
        quickSort(arr, low, pi-1) 
        quickSort(arr, pi+1, high) 

arr = [10, 7, 8, 9, 1, 5] 
n = len(arr) 
quickSort(arr,0,n-1) 


def quick_sort(s):
    """快速排序,s为列表"""
    # 结束条件
    if len(s) < 2:
        return
    # 从列表取出一个元素作为基准值
    p = s[0]
    L = [] # 小于
    E = [] # 等于
    R = [] # 大于
    # 把s里的元素放入3个队列
    while len(s) > 0:
        if s[-1] < p:
            L.append(s.pop())
        elif s[-1] == p:
            E.append(s.pop())
        else:
            R.append(s.pop())

    quick_sort(L)
    quick_sort(R)
    s.extend(L)
    s.extend(E)
    s.extend(R)
    
s = [1, 7, 3, 5, 4]
quick_sort(s)
print(s)

2.3 选择排序

# 首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
# 再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
# 重复第二步,直到所有元素均排序完毕。
def selectsort(arr):
    for i in range(len(arr)-1):
        m = i
        for j in range(i+1,len(arr)):
            if arr[j] < arr[m]:
                m = j
        if i != m:
            arr[i],arr[m] = arr[m],arr[i]
    return arr 

a = [20,7,9,10,3]
selectsort(a)

2.4 插入排序

# 将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。
# 从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)
def insertsort(arr):
    for i in range(len(arr)):
        p = i-1
        c = arr[i]
        while p >= 0 and arr[p] > c:
            # 从最后一个开始比对,由于arr已经是排好的了,所以只要找到比要比较的c小的就可以
            arr[p+1] = arr[p]
            p -= 1
        arr[p+1] = c 
    return arr
a = [20,7,9,10,3]
insertsort(a)

2.5 希尔排序

def shellSort(arr):
    import math
    gap=1
    while(gap < len(arr)/3):
        gap = gap*3+1
    while gap > 0:
        for i in range(gap,len(arr)):
            temp = arr[i]
            j = i-gap
            while j >=0 and arr[j] > temp:
                arr[j+gap]=arr[j]
                j-=gap
            arr[j+gap] = temp
        gap = math.floor(gap/3)
    return arr
a = [20,7,9,10,3]
shellSort(a)

2.6 归并排序

def mergeSort(arr):
    import math
    if(len(arr)<2):
        return arr
    middle = math.floor(len(arr)/2)
    left, right = arr[0:middle], arr[middle:]
    return merge(mergeSort(left), mergeSort(right))

def merge(left,right):
    result = []
    while left and right:
        if left[0] <= right[0]:
            result.append(left.pop(0))
        else:
            result.append(right.pop(0));
    while left:
        result.append(left.pop(0))
    while right:
        result.append(right.pop(0));
    return result
a = [20,7,9,10,3]
mergeSort(a)

2.7 堆排序

def buildMaxHeap(arr):
    import math
    for i in range(math.floor(len(arr)/2),-1,-1):
        heapify(arr,i)

def heapify(arr, i):
    left = 2*i+1
    right = 2*i+2
    largest = i
    if left < arrLen and arr[left] > arr[largest]:
        largest = left
    if right < arrLen and arr[right] > arr[largest]:
        largest = right

    if largest != i:
        swap(arr, i, largest)
        heapify(arr, largest)

def swap(arr, i, j):
    arr[i], arr[j] = arr[j], arr[i]

def heapSort(arr):
    global arrLen
    arrLen = len(arr)
    buildMaxHeap(arr)
    for i in range(len(arr)-1,0,-1):
        swap(arr,0,i)
        arrLen -=1
        heapify(arr, 0)
    return arr
a = [20,7,9,10,3]
heapSort(a)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值