zoukankan      html  css  js  c++  java
  • 18.四数之和(中等)

    18.四数之和

    题目链接:四数之和(中等)

    题目描述

    给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):

    • 0 <= a, b, c, d < n

    • a、b、c 和 d 互不相同

    • nums[a] + nums[b] + nums[c] + nums[d] == target 你可以按任意顺序返回答案 。

    示例 1:

    输入:nums = [1,0,-1,0,-2,2], target = 0
    输出:[[-2,-1,1,2],[-2,0,0,2],[-1,0,0,1]]

    示例 2:

    输入:nums = [2,2,2,2,2], target = 8
    输出:[[2,2,2,2]]

    提示:

    1 <= nums.length <= 200
    -109 <= nums[i] <= 109
    -109 <= target <= 109

    题解

    思路:三数之和一样,只不过多了一层循环

    代码(C++版本)

    vector<vector<int>> fourSum(vector<int>& nums, int target) {
       vector<vector<int>> result;
       if(nums.size() < 4) return result;
       sort(nums.begin(), nums.end());
       //a=i,b=j,c=left,d=right
       for (int i = 0; i < nums.size() - 3; i++) {
           //对 a 进行去重
           if (i > 0 && nums[i] == nums[i - 1]) {
               continue;
          }
           //j一开始指向i所指元素的后一位
           for (int j = i + 1; j < nums.size() - 2; j++) {
               //对 b 进行去重
               if (j > i + 1 && nums[j] == nums[j - 1]) {
                   continue;
              }
               int left = j + 1;
               int right = nums.size() - 1;
               while (left < right) {
                   // 如果直接求出 nums[i] + nums[j] + nums[left] + nums[right] 的和可能出现溢出的情况
                   int tmp = target - nums[i] - nums[j];
                   //如果找到满足条件的元组,左指针和右指针同时收缩
                   if ( nums[left] + nums[right] == tmp) {
                       result.push_back({nums[i], nums[j], nums[left], nums[right]});
                       //找到满足条件的元组后,对left和right进行去重
                       while (left < right && nums[left + 1] == nums[left]) {
                           left++;
                      }
                       while (left < right && nums[right - 1] == nums[right]) {
                           right--;
                      }
                       left++;
                       right--;
                  }
                   //元组的和大于target,右指针收缩,使和变小
                   else if (nums[left] + nums[right] > tmp) {
                       right--;
                  }
                   //元组的和小于target,左指针收缩,使和变大
                   else if (nums[left] + nums[right] < tmp) {
                       left++;
                  }
              }
          }
      }
       return result;
    }

    分析:

    • 时间复杂度:O(n^3)。排序的时间复杂度是O(nlogn),枚举四元组的时间复杂度是 O(n^3)。

    • 空间复杂度:O(logn)。空间复杂度主要取决于排序额外使用的空间。此外排序修改了输入数组 nums,实际情况中不一定允许,因此也可以看成使用了一个额外的数组存储了数组 nums 的副本并排序,空间复杂度为 O(n)。

  • 相关阅读:
    Oracle 用 sqlprompt 修改 sqlplus 提示符
    Oracle cursor pin S wait on X 等待事件 说明
    Oracle 利用 rowid 提升 update 性能
    Oracle 从缓存里面查找真实的执行计划
    Linux 进程状态 说明
    Oracle 用户 对 表空间 配额(quota ) 说明
    Upon startup of Linux database get ORA27102: out of memory LinuxX86_64 Error: 28: No space left on device
    异常宕机 Ora00600 [Kccpb_sanity_check_2] 错误解决方法
    Oracle ORA04031 错误 说明
    Oracle Shared pool 详解
  • 原文地址:https://www.cnblogs.com/wltree/p/15488591.html
Copyright © 2011-2022 走看看