15. 3Sum & 16. 3Sum Closest

这两个题非常相似,所以放在一起了

题目

Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != ji != k, and j != k, and nums[i] + nums[j] + nums[k] == 0.

Notice that the solution set must not contain duplicate triplets.

 

Example 1:

Input: nums = [-1,0,1,2,-1,-4]
Output: [[-1,-1,2],[-1,0,1]]

Example 2:

Input: nums = []
Output: []

Example 3:

Input: nums = [0]
Output: []

 

Constraints:

  • 0 <= nums.length <= 3000
  • -105 <= nums[i] <= 105

解法:

解法一:

解法一的时间复杂度是O(n^{2}),因为最近主要在练习python,所以贴评论区python解法

def threeSum(self, nums):
    res = []
    nums.sort()
    for i in xrange(len(nums)-2):
        #去重,因为nums[i-1]的时候,已经将[i,len(nums)-1]范围内所有可能的组合都添加到结果集中#了。如果nums[i]的可能结果集范围比nums[i-1]小,为[i+1,len(nums)-1]。如果nums[i]=nums[i-#1],则需跳过nums[i]防止重复。
        if i > 0 and nums[i] == nums[i-1]:
            continue
        l, r = i+1, len(nums)-1#分别是左右两个指针
        while l < r:
            s = nums[i] + nums[l] + nums[r]
            if s < 0:#因为nums已经从小到大排好了,当和小于0时,就希望用更大的值,所以左边加一
                l +=1 
            elif s > 0:#当和大于0时,希望用更小的值,所以右边减一
                r -= 1
            else:
                res.append((nums[i], nums[l], nums[r]))
                while l < r and nums[l] == nums[l+1]:#去重
                    l += 1
                while l < r and nums[r] == nums[r-1]:#去重
                    r -= 1
                l += 1; r -= 1
    return res

解法二:

我自己的思路,算法复杂度是O(n^{2})logN,在倒数第三个案例会跑不过去,超时。和解法一的区别在于找第二第三个元素时,我是固定第三个元素,用二分法找第二个元素,复杂度O(nlogn)。而解法一是从两边向中间遍历,复杂度为O(n)。

我的算法每次固定左边的元素i和右边的元素j,然后用二分法找中间的元素。就这个题而言是无法ac的,倒数第三个测试案例通不过,超时。就是记录下自己的想法

    def threeSum(self, nums: List[int]) -> List[List[int]]:
        result=[]
        if(nums is None or len(nums)<3):
            return result
        nums.sort()
        start=stop=0
        for i in range(0,len(nums)-2):#左边的数
            #去重
            if(i>0 and nums[i]==nums[i-1]):
                continue
            start=I#二分法的左端
            for j in range(len(nums)-1,i+1,-1):#右边的数
                if (j < len(nums) - 1 and nums[j + 1] == nums[j]):#去重
                    continue
                stop=j#二分法的右端
                p=(i+j)//2#中间的数
                while(p>i and p<j):
                    if(nums[i]+nums[j]+nums[p]==0):
                        result.append([nums[i],nums[p],nums[j]])
                        break
                    elif(nums[i]+nums[j]+nums[p]>0):
                        stop=p
                        p=(p+start)//2
                    else:
                        if(p==stop-1):#防止死循环
                            break
                        start=p
                        p=(p+stop)//2

        return result

16. 3Sum Closest题目

Given an array nums of n integers and an integer target, find three integers in nums such that the sum is closest to target. Return the sum of the three integers. You may assume that each input would have exactly one solution.

 

Example 1:

Input: nums = [-1,2,1,-4], target = 1
Output: 2
Explanation: The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).

 

Constraints:

  • 3 <= nums.length <= 10^3
  • -10^3 <= nums[i] <= 10^3
  • -10^4 <= target <= 10^4

解法:

这个跟15题太相似了,直接贴O(n^{2})解法,这个代码精简很多,因为题目中讲了有且仅有一个答案,不用考虑去重或者为空的情况。

def threeSumClosest(self, num, target):
        num.sort()
        result = num[0] + num[1] + num[2]
        for i in range(len(num) - 2):
            j, k = i+1, len(num) - 1
            while j < k:
                sum = num[i] + num[j] + num[k]
                if sum == target:
                    return sum
                
                if abs(sum - target) < abs(result - target):
                    result = sum
                
                if sum < target:
                    j += 1
                elif sum > target:
                    k -= 1

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include &lt;stdio.h&gt; #include &lt;string.h&gt; #include &lt;stdlib.h&gt; typedef struct { int no; char info; } VertexType; typedef struct { int edges[MAXV][MAXV]; int n, e; VertexType vexs[MAXV]; } MatGraph; void CreatMat(MatGraph &amp;g, int A[MAXV][MAXV], int n, int e) { int i, j; g.n = n; g.e = e; for (i = 0; i &lt; g.n; i++) for (j = 0; j &lt; g.n; j++) g.edges[i][j] = A[i][j]; } void DispMat(MatGraph g) { int i, j; for (i = 0; i &lt; g.n; i++) { for (j = 0; j &lt; g.n; j++) if (g.edges[i][j] != INF) printf(&quot;%4d&quot;, g.edges[i][j]); else printf(&quot;%4s&quot;, &quot;&infin;&quot;); printf(&quot;\n&quot;); } } int Prim(MatGraph g, int v) { int lowcost[MAXV], min, n = g.n, sum; int closest[MAXV], i, j, j; for (i = 0; i &lt; n; i++) { lowcost[i] = g.edges[v][i]; closest[i] = v; } for (i = 1; i &lt; n; i++) { min = INF; for (j = 0; j &lt; n; j++) if (lowcost[j] != 0 &amp;&amp; lowcost[j] &lt; min) { min = lowcost[j]; k = j; } printf(&quot;\n 城市%d和城市%d之间的最短距离为:%d\n&quot;, closest[k] + 1, k + 1, min * 10); sum = sum + min; lowcost[k] = 0; for (j = 0; j &lt; n; j++) if (g.edges[k][j] != 0 &amp;&amp; g.edges[k][j] &lt; lowcost[j]) { lowcost[j] = g.edges[k][j]; closest[j] = k; } } return sum; } int main() { int v = 3, k; MatGraph g; int A[MAXV][MAXV] = { {0, 6, 1, 5, INF, INF}, {6, 0, 5, INF, 3, INF}, {1, 5, 0, 5, 6, 4}, {5, INF, 5, 0, INF, 0, 6}, {INF, 3, 6, INF, 0, 6}, {INF, INF, 4, 2, 6, 0} }; int n = 6, e = 10; CreateMat(g, A, n, e); printf(&quot;城市连接图的邻接矩阵:\n&quot;); DispMat(g); printf(&quot;\n普利姆算法求解结果:\n&quot;); k = Prim(g, 0); printf(&quot;\n各个城市之间的总最短距离为:%d千米\n&quot;, k * 10); return 1; }改bug
06-10

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值