题目:python
给定一串数字
判断是否存在这三个元素,它们将数字串分为四个子串,其中每一个子串的数字之和均相同(该3个元素不归入计算)
要求时间复杂度和空间复杂度均不能超过O(n)app
# -*- coding: utf-8 -*- import random def split_to_four(n): nums = [] for i in range(n): nums.append(random.randint(0, 99)) # nums = [2, 1, 1, 1, 85, 1, 1, 1, 2] # nums = [5,1,3,1,1,3,3,2,2,1,1,1,1,1] print nums # i 三元素中左侧元素索引 # j 三元素中右侧元素索引 i, j = 1, len(nums) - 1 total = sum(nums) k = None # 三元素中中间元素索引 # 当i<j,而且中间k还没找到时,继续循环 while i < j and k is None: i, j, k = find_3th_points(i, j, nums, total) if k is None: return [] return i, k, j def find_3th_points(i, j, nums, total): """ 根据左右两个点找中间的第三个点 :param i: :param j: :param nums: :param total: :return: """ i, j = find_two_points_on_side(i, j, nums) # 假如i,j都交叉了都没找到左右和相等的状况,那么确定不存在这3个元素 if i >= j: return i, j, None # 假如找到左右的位置,那么就把i,j位置中间的元素进行计算, # 若是知足总值-左值-右值-中间的值%4==0,以及中间分隔的这段和边上的同样, # 那么就找到这个k了,结束程序返回 # 若是循环完了尚未这个k,则左右都往中间走,继续找两侧相等的i,j点,继续计算 for k in range(i + 1, j): if (total - nums[i] - nums[j] - nums[k]) % 4 == 0 and sum(nums[:i]) == sum(nums[i + 1:k]): return i, j, k return i + 1, j - 1, None def find_two_points_on_side(i, j, nums): """ 找出两侧分隔元素的位置 从左侧和右侧分别求和判断是否相等,相等则认为找到i,j,不然根据左右和的大小判断是i往前走1,仍是j往左侧走1 :param i: :param j: :param nums: :return: """ while i < j: if sum(nums[:i]) > sum(nums[j:]): j -= 1 elif sum(nums[:i]) < sum(nums[j:]): i += 1 else: return i, j - 1 return i, j print split_to_four(10)
注意是利用左右两侧数据和相等的特性,再根据4个和相等的特性,找到左右2个,那么总和减去左右2个线,再从中间找个线,能分隔出4个相等的和即为找到了dom