每天一道leetcode——《k-avoiding数组的最小总和数》

一、题目

给你两个整数 n 和 k 。

对于一个由 不同 正整数组成的数组,如果其中不存在任何求和等于 k 的不同元素对,则称其为 k-avoiding 数组。

返回长度为 n 的 k-avoiding 数组的可能的最小总和。

二、最基础的解题思路

最开始我的想法就是建立一个set()集合,从i=1开始一直往后,判断k-i在不在这个set()集合中,如果不在就把i存进去,一直存到set()集合的大小为n为止:

每天一道leetcode——《k-avoiding数组的最小总和数》_第1张图片

但是发现这样的时间复杂度太高了,是O(klogn),而且在leetcode官方上面提交的时候,显示运行超时。

三、结合数学思想的解题思路

  任意两个数相加需要小于k,那什么情况下,必然会得到两个数相加小于k呢?那就需要以k/2和k    为界限了。在k/2以下,任意两个数相加肯定是不会等于k的,而且也能保证是最小的数。这是最    理想的情况。如果这些数不够n,那就再从k以上,依次存入,也能保证保证任意两个数相加不等于k,这样的条件下也能满足和是最小的。其实这个跟上面的一个一个遍历是一样的。举个例子,假如k=10,n=10。那么从1开始遍历,1,2,3,4,5(k/2),都可以存进去,但是到6,7,8,9就不行了,因为k-i已经在这个集合中了,所以就只能从10开始,10(k),11,12,13,14截止,使得集合大小为n。本质上是一样的,只是使用数学的思想简化了一下,求和也可以借用数学数列等差公式求和,这样也能很大程度上优化时间复杂度。

每天一道leetcode——《k-avoiding数组的最小总和数》_第2张图片

四、总结

这个例题让我明白,在写算法的时候,思维应该开放点,往往很多循环,遍历,是可以简化的,因为它们深层次上表达的意思是一样的,但是换一种方式去解决的话,时间效率上却能优化不少。

你可能感兴趣的:(leetcode,算法,数据结构)