面试手写算法题总结

1.Two Sum问题,给定一个数组 nums找到数组中两个数之和为给定值所有或者(找到即可)组合。

暴力搜索效率很低,这里用类似双指针可以让时间复杂度达到O(N)

def two_sum(nums, target):
    res = []
    nums.sort()
    if len(nums) < 2:
        return res
    elif nums[0] >= target:
        return res
    else:
        begin = 0
        end = len(nums)-1
        while begin < end:
            if nums[begin] + nums[end] == target:
                temp = [nums[begin], nums[end]]
                res.append(temp)
                begin += 1; end -= 1
            elif nums[begin] + nums[end] > target:
                end -= 1
            else:
                begin += 1
        return res
nums = [1, 3, -2, 0, 5, 4, 6, 4, 7]
target = 9
print(two_sum(nums, target))

还有利用python里的字典来解决的(这里返回的是索引,当然也可以返回具体的值,不太明白这里的复杂度是多少):

def twoSum(num, target):
    dict = {}
    for i in range(len(num)):
        x = num[i]
        if target - x in dict:
            return (dict[target - x], i)
        dict[x] = i
num = [-3,-2,0,1,2,4,5,7,-1]
print(twoSum(num, 12))

2. threesum问题: 

def threeSum(nums):
    res = []
    length=len(nums)
    if length<3:return res
    nums.sort()
    for i in range(length):
        if nums[i]>0:break
        if i>0 and nums[i]==nums[i-1]:continue
        begin=i+1;end=length-1
        while begin < end:
            sum=nums[i]+nums[begin]+nums[end]
            if sum==0:
                tmp=[nums[i],nums[begin],nums[end]]
                res.append(tmp)
                begin+=1;end-=1
                while begin < end and nums[begin] == nums[begin - 1]: begin += 1
                while begin < end and nums[end] == nums[end + 1]: end -= 1
            elif sum>0:end-=1
            else:begin+=1
    return res
nums = [-1,0,1,7,-6,3,5]
print(threeSum(nums))

更新threeSum问题:(指定一个数,然后用两个指针类似于二分查找)

def threeSum(nums):
    ans = []
    nums.sort()
    for i in range(len(nums) - 2):
        if i == 0 or nums[i] > nums[i - 1]:  # 如果后个和前个相等,那么后一个能实现相加为target必然和前面重复
            left = i + 1
            right = len(nums) - 1
            while left < right:
                target = nums[left] + nums[right] + nums[i]
                if target == 0:
                    ans.append([nums[i], nums[left], nums[right]])
                    left += 1
                    right -= 1
                    while left < right and nums[left] == nums[left-1]:  # skip duplicates
                        left += 1                                       #两个while也体现了一点点分治
                    while left < right and nums[right] == nums[right+1]:#这两个while可以一直跳转到最后的
                        right -= 1                                      #数的位置如[-2,0,0,2,2]跳转到32
                elif target < 0:                                        #注意while最后的状态是第一个不满足条件的位置
                    left += 1
                else:
                    right -= 1
    return ans

3. 最长递增子序列问题:

用贪心的思想:(从前往后,每个数做标记,当前数上的标记为前面比他小的数上最大标记+1,很容易理解,这样延伸到当前数时可保证是最长的递增序列)代码如下:

def dp(nums):
    d = [0]
    re = [[0] for k in nums]
    for i in range(1, len(nums)):
        for j in range(i):
            if nums[j] < nums[i]:
                re[i].append(d[j]+1)
        d.append(max(re[i]))
    return max(d)+1
nums = [1,3,2,4]
print(dp(nums))

用动态规划来做:

4. 求字符串最长回文子串的长度(回文子串即是对称的连续子串)中心展开法,考虑bb这种所以每个字符插入‘#’:

def func(arr):
    re = []
    new_arr = ''
    for i in arr:
        new_arr += i+'#'
    for i in range(2, len(new_arr)-2, 2):
        j = 1
        count = 0
        while i-j >= 0 and i+j <= len(new_arr)-1:
            if new_arr[i-j] == new_arr[i+j]:
                count += 1
                j += 1
            else:
                break
        re.append(count)
    return max(re)+1

arr = 'cabacd'
print(func(arr))

    原文作者:LLM666Coder
    原文地址: https://blog.csdn.net/LLM666Coder/article/details/79772411
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞