題目: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