20240131-将数组划分为具有最大差异的数组

该篇文章介绍了一种算法,用于解决给定整数数组和正整数k,如何将其划分为满足元素差不超过k的3个子数组。通过先排序数组并检查差值,作者提供了详细的步骤和C++代码实现,指出排序和遍历的时间复杂度为O(nlogn),空间复杂度为O(n)。
摘要由CSDN通过智能技术生成

这两天比较忙,之后如果有时间会慢慢补拉下的题目。

题目要求

给你一个大小为 n 的整数数组 nums 和一个正整数 k。

将数组划分为一个或多个大小为 3 的数组,并满足以下条件:

  • 数组 nums 中的每个元素都应恰好位于一个数组中。
  • 一个数组中任意两个元素之差小于或等于 k。
  • 返回一个包含所有数组的 2D 数组。如果无法满足条件,则返回空数组。如果有多个答案,则返回其中任意一个。

Example 1:

Input: nums = [1,3,4,8,7,9,3,5,1], k = 2
Output: [[1,1,3],[3,4,5],[7,8,9]]
Explanation: We can divide the array into the following arrays: [1,1,3], [3,4,5] and [7,8,9].
The difference between any two elements in each array is less than or equal to 2.
Note that the order of elements is not important.

Example 2:

Input: nums = [1,3,3,2,7,3], k = 3
Output: []
Explanation: It is not possible to divide the array satisfying all the conditions.

思路

首先仔细看题目中的要求,每个数字在子数列中出现恰好1次,同时n一定是3的倍数。那么我们就不需要考虑重复值、复杂判断的问题了,给每个数字安排他们的位置即可。

那么想到我们需要首先对数组进行排序,因为数组经过排序后相邻元素的差值最小。这意味着如果排序后的数组中存在任何相邻元素之间的差值大于k,那么将这些元素分配到满足条件的大小为3的子数组中就不可能了。反过来,如果排序后的数组中所有相邻元素的差值都不大于k,那么我们就可以三个一组的构建数组了。

那么我们梳理一下步骤:

  1. 对原始数组进行排序。(如果原始数组为空,则不可能组成子数组。)
  2. 首先子数组为空,每次对子数组加入元素的时候判断,加入新的元素是否会破坏差值最大为k的结构。如果破坏则直接返回false,因为我们已经排序,当前num不行,后续num也不行。
  3. 如果当前子数组的长度为3,push_back进入result成为一个解,然后temp.clear()清理当前子数组。

代码

class Solution {
public:
    bool check_diff(vector<int>& temp, int num, int k) {
        if (temp.empty() || abs(temp[0] - num) <= k && abs(temp.back() - num) <= k) {
            return true;
        }
        return false;
    }
    vector<vector<int>> divideArray(vector<int>& nums, int k) {
        if (nums.size() < 3) {
            return vector<vector<int>>();
        }
        sort(nums.begin(), nums.end());
        vector<int> temp;
        vector<vector<int>> result;
        for (int num : nums) {
            if (temp.size() < 3) {
                if (check_diff(temp, num, k)) {
                    temp.push_back(num);
                } else {
                    return vector<vector<int>>();
                }
            }
            if (temp.size() == 3) {
                result.push_back(temp);
                temp.clear();
            }
        }
        return result;
    }
};

排序时间复杂度O(nlogn),遍历数组O(n),总体时间复杂度O(nlogn)。空间上创建二维数组存储result,复杂度O(n)。

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值