算法问题中的code题目

目录

Top K问题

最长公共子串

最长公共子序列

最长递增字串(O(N))

最长无重复子串O(N)

实现sqrt()函数

从数组A中找出所有和为S的两个数的索引

无序数组的中位数  (利用小顶堆)

超过数组个数一半的数

将一个二维的n*n的数组,逆转90度,空间复杂度是O(1)。提示:剥洋葱般,一圈圈的从外向内逆转90度

一个大小为N的数组,里面的值代表的是股价,求一次买入卖出所能够求得最大收益


 


 

Top K问题

#topk 最小
class Solution:
    def find_topk(self, arr, k):
        if len(arr) < k or k < 0:
            return False
        #建立大根堆
        #第一次建立大根堆需要从最后一个非叶子节点开始
        for i in range((k-1)//2, -1, -1):
            self.build_max_head(arr, k, i)
        for j in range(k, len(arr)):
            if arr[j] < arr[0]:
                arr[0] = arr[j]
                self.build_max_head(arr, k, 0)
        for i in range(k-1,-1,-1):
            arr[0], arr[i] = arr[i], arr[0]
            self.build_max_head(arr, i, 0)
        return arr[:k]

    def build_max_head(self, arr, length, root):
        max = root
        left = root*2 + 1
        right = left + 1
        if left < length and arr[left] > arr[max]:
            max = left
        if right < length and arr[right] > arr[max]:
            max = right
        if max != root:
            arr[max], arr[root] = arr[root], arr[max]
            self.build_max_head(arr, length, max)

re = Solution().find_topk([3,4,6,7,8,1,2], 4)
print(re)

最长公共子串

# coding:utf-8
'''
求两个字符串的最长公共子串
思想:建立一个二维数组,保存连续位相同与否的状态
'''
 
def getNumofCommonSubstr(str1, str2):
 
    lstr1 = len(str1)
    lstr2 = len(str2)
    record = [[0 for i in range(lstr2+1)] for j in range(lstr1+1)]  # 多一位
    maxNum = 0          # 最长匹配长度
    p = 0               # 匹配的起始位
 
    for i in range(lstr1):
        for j in range(lstr2):
            if str1[i] == str2[j]:
                # 相同则累加
                record[i+1][j+1] = record[i][j] + 1
                if record[i+1][j+1] > maxNum:
                    # 获取最大匹配长度
                    maxNum = record[i+1][j+1]
                    # 记录最大匹配长度的终止位置
                    p = i + 1
    return str1[p-maxNum:p], maxNum
 
 
if __name__ == '__main__':
    str1 = 'abcdef'
    str2 = 'ydufdsbhgcdeftyh'
 
    res = getNumofCommonSubstr(str1, str2)
    print(res)

最长公共子序列

import numpy

def find_lcseque(s1, s2): 
	 # 生成字符串长度加1的0矩阵,m用来保存对应位置匹配的结果
	m = [ [ 0 for x in range(len(s2)+1) ] for y in range(len(s1)+1) ] 
	# d用来记录转移方向
	d = [ [ None for x in range(len(s2)+1) ] for y in range(len(s1)+1) ] 
 
	for p1 in range(len(s1)): 
		for p2 in range(len(s2)): 
			if s1[p1] == s2[p2]:            #字符匹配成功,则该位置的值为左上方的值加1
				m[p1+1][p2+1] = m[p1][p2]+1
				d[p1+1][p2+1] = 'ok'          
			elif m[p1+1][p2] > m[p1][p2+1]:  #左值大于上值,则该位置的值为左值,并标记回溯时的方向
				m[p1+1][p2+1] = m[p1+1][p2] 
				d[p1+1][p2+1] = 'left'          
			else:                           #上值大于左值,则该位置的值为上值,并标记方向up
				m[p1+1][p2+1] = m[p1][p2+1]   
				d[p1+1][p2+1] = 'up'         
	(p1, p2) = (len(s1), len(s2)) 
	print(numpy.array(d))
	s = [] 
	while m[p1][p2]:    #不为None时
		c = d[p1][p2]
		if c == 'ok':   #匹配成功,插入该字符,并向左上角找下一个
			s.append(s1[p1-1])
			p1-=1
			p2-=1 
		if c =='left':  #根据标记,向左找下一个
			p2 -= 1
		if c == 'up':   #根据标记,向上找下一个
			p1 -= 1
	s.reverse() 
	return ''.join(s) 
 
print(find_lcseque('bcdfg','abdfgh'))

最长递增字串(O(N))

'''
最长连续递增子序列
dp[i]以nums[i]结尾的最长递增子序列的长度
if nums[i] > nums[j], 说明nums[i]能缀到nums[j]后面,
那么dp[i]就能+1了
dp[i+1] = max(dp[i + 1], dp[j] + 1)
'''
 
 
def length_of_lis(nums):
    len_nums = len(nums)
    if len_nums == 0:
        return 0
 
    dp = [1] * len_nums
    for i in range(len_nums - 1):
        for j in range(i + 1):
            # 如果nums[i+1]能缀在nums[j]后面的话,就dp[j]+1
            if nums[i + 1] > nums[j]:
                # 缀完的结果还要看看是不是比我大
                dp[i + 1] = max(dp[i + 1], dp[j] + 1)
    return max(dp)
 
 
if __name__ == '__main__':
    nums = [10, 9, 2, 5, 3, 7, 101, 18]
    res = length_of_lis(nums)
    print(res)

最长无重复子串O(N)

def lengthOfLongestSubstring(s):
        # write your code here
        res = 0
        if s is None or len(s) == 0:
            return res
        d = {}
        tmp = 0
        start = 0
        for i in range(len(s)):
            if s[i] in d and d[s[i]] >= start:
                start = d[s[i]] + 1
            tmp = i - start + 1
            d[s[i]] = i
            res = max(res, tmp)
        return res

print(lengthOfLongestSubstring('abcabcbc'))

实现sqrt()函数

  • 二分法
def sqrt_binary(x):
    low = 0
    high = max(1, x)
    guess = (low + high)/2
    count = 1
    while abs(guess**2 - x) > 0.000000001 and count < 100:
        if guess**2 < x:
            low = guess
        else:
            high = guess
        guess = (low + high) / 2
        count += 1
    return guess
  • 牛顿迭代法:

         原理:https://blog.csdn.net/ccnt_2012/article/details/81837154

         code:https://blog.csdn.net/Everywhere_wwx/article/details/80254286

class Solution(object):
    def mySqrt(self, x):
        """
        :type x: int
        :rtype: int
        """
        re = 1.0
        while abs(re*re - x)abs > 0.0001:
            re = (re + x/re)/2
        return int(re)

从数组A中找出所有和为S的两个数的索引

  • 先快排,前后两指针和查找 O(NlogN)
def getres(nums, target):
    num = sorted(nums)
    low, high = 0, len(nums)-1
    res = []
    while low < high:
        if num[low] + num[high] == target:
            res.append((num[low], num[high]))
            low += 1
            high -=1
        elif num[low] + num[high] < target:
            low += 1
        else:
            high -= 1
    return res

print(getres([1, 4, 3, 2, 6 ,5], 6))
  • 哈希思想O(N)
# 哈希表思想
def getRes_HashMap(nums, target):
    result = []
    for i, value in enumerate(nums):
        if (target - value) in nums[i+1:]:
            result.append((value, target - value))
    return result

print(getRes_HashMap([1, 4, 3, 2, 6 ,5], 6))

无序数组的中位数  (利用小顶堆)

def heap_adjust(parent,heap):   #更新结点后进行调整
    child=2*parent+1
    while len(heap)>child:
        if child+1<len(heap) and heap[child+1]<heap[child]:
            child+=1
        if heap[parent]<=heap[child]:
            break
        heap[parent],heap[child]=heap[child],heap[parent]
        parent,child=child,child*2+1
 
def find(nums):
    k=len(nums)//2 +1
    heap=nums[:k]
    for i in range(k,-1,-1):   #前n/2个元素建堆
        heap_adjust(i,heap)
    for j in range(k,len(nums)):
        if nums[j]>heap[0]:
            heap[0]=nums[j]
            heap_adjust(0,heap)
    #奇数时是最中间的数,偶数时是最中间两数的均值
    return heap[0] if len(nums)%2==1 else float(heap[0]+min(heap[1],heap[2]))/2
 
print(find([1,2,8,9,3,5,4,6,7,0]))
print(find([4,5,3,7,2,6,1]))

超过数组个数一半的数

def Morethanhalfnum(nums):
    l1 = len(nums)
    if l1 <= 1:
        return nums
    a, b = nums[0], 1
    for i in range(1, l1):
        if a == nums[i]:
            b += 1
        elif b == 0:
            a = nums[i]
            b += 1
        else:
            b -= 1
    count = 0
    for j in range(l1):
        if nums[j] == a:
            count += 1
    if count>l1/2:
        return a
    else:
        return 0

print(Morethanhalfnum([1,2,3,2,2,2,5,4,2]))

将一个二维的n*n的数组,逆转90度,空间复杂度是O(1)。提示:剥洋葱般,一圈圈的从外向内逆转90度

data=[[i for i in range(4)] for raw in range(4)]
for ele in data:
    print(ele)

a=len(data)
for i in range(a):#外层循环
    for j in range(i+1,len(data[i])): #内层循环
        #交换数据
        temp=data[i][j]
        data[i][j]=data[j][i]
        data[j][i]=temp
        
for ele in data:
    print(ele)

一个大小为N的数组,里面的值代表的是股价,求一次买入卖出所能够求得最大收益

def best_time(nums):
    l1 = len(nums)
    if l1 == 1:
        return 0
    max = 0
    min = nums[0]
    for i in range(l1):
        if nums[i] < min:
            min = nums[i]
        elif max < nums[i]-min:
            max = nums[i] - min
    return max

in_nums = [7,1,5,3,6,4]

print(best_time(in_nums))

二叉树遍历

前序

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def __init__(self):
        self.res = []
    def preorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        # if not root:
        #     return None
        # self.res.append(root.val)
        # self.preorderTraversal(root.left)
        # self.preorderTraversal(root.right)
        # return self.res
        res, stack = [], []
        if root:
            stack.append(root)
        while stack:
            node = stack.pop()
            res.append(node.val)
            if node.right:
                stack.append(node.right)
            if node.left:
                stack.append(node.left)
        return res

中序

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def __init__(self):
        self.res = []
    def inorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root:
            return None
        # self.inorderTraversal(root.left)
        # self.res.append(root.val)
        # self.inorderTraversal(root.right)
        # return self.res
        stack, node = [], root
        res = []
        while stack or node:
            while node:
                stack.append(node)
                node = node.left
            node = stack.pop()
            res.append(node.val)
            node = node.right
        return res
                
        

后序

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def __init__(self):
        self.res = []
    def postorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root:
            return None
        # self.postorderTraversal(root.left)
        # self.postorderTraversal(root.right)
        # self.res.append(root.val)
        # return self.res
        stack, res = [root], []
        while stack:
            node = stack.pop()
            if node.left:
                stack.append(node.left)
            if node.right:
                stack.append(node.right)
            res.append(node.val)
        return res[::-1]

层次遍历

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def levelOrder(self, root):
        """
        :type root: TreeNode
        :rtype: List[List[int]]
        """
        levels = []
        if not root:
            return levels
        
        def everylevel(root, level):
            if len(levels) == level:
                levels.append([])
            levels[level].append(root.val)
            if root.left:
                everylevel(root.left, level+1)
            if root.right:
                everylevel(root.right, level+1)
        everylevel(root,0)
        return levels

链表快排

作者:算法才是灵魂
链接:https://www.nowcoder.com/discuss/220011?type=0&order=0&pos=51&page=1
来源:牛客网

class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None
 
class Solution:
    def sortList(self, head: ListNode) -> ListNode:
        if head == None or head.next == None:
            return head
        leftH = ListNode(0)
        resL = leftH
        rightH = ListNode(0)
        resR = rightH
        midNode = head
        head = head.next
        while head != None:
            if head.val < midNode.val:
                leftH.next = head
                leftH = leftH.next
            else:
                rightH.next = head
                rightH =rightH.next
            head = head.next
        leftH.next = None
        rightH.next = None
        L = self.sortList(resL.next)
        R = self.sortList(resR.next)
        midNode.next = R
        if L == None:
            return midNode
        tmp = L
        while tmp.next != None:
            tmp = tmp.next
        tmp.next = midNode
        return L

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值