LintCode 1529: Triplet Subarray With Absolute Diff Less Than or Equal to Limit (同向双指针经典题)

本文介绍了一种高效算法,用于在给定的整数数组中找出所有满足特定条件的三元子数组,即任意两个元素之间的绝对差小于等于预设限制。通过使用双指针技巧,该算法能够在O(n)的时间复杂度内解决问题。

1529. Triplet Subarray With Absolute Diff Less Than or Equal to Limit

Given an increasing array of integers nums and an integer limit, return the number of the triplet subarray in which the absolute difference between any two elements is less than or equal to limit.

In case there is no subarray satisfying the given condition return 0.

Example

Example 1:

Input:[1, 2, 3, 4], 3
Output:4
Explanation:We can choose (1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4). Therefore, the number of the triplet subarray is 4.

Example 2:

Input: [1, 10, 20, 30, 50], 19
Output:1
Explanation:The only triplet array is (1, 10, 20), so the answer is 1。

Challenge

Can you figure out a solution with time complexity of O(n)?

Notice

1 ≤ len(nums) ≤ 1e4,1 ≤ limit ≤ 1e6,0 ≤ nums[i] ≤ 1e6
Since the answer may be too large, return it modulo 99997867.

Input test data (one parameter per line)How to understand a testcase?


解法1:这题本来可以用DP,但DP可能要O(N^2),而这里数据量太大,所以采用双指针。

思路,p2先行。当nums[p2]-nums[p1]>limit时,说明p1..p2这个range还不符合要求,所以p1必须++,当p1符合条件后跳出while循环,此时我们可以看出,p1, p1+1, ... p2这个range,p2固定,p1..p2-1里面任取2数都可以满足3数之中任意之差的绝对值<=limit,所以count+=((p2 - p1) * (p2 - p1 - 1) / 2)。这里采用组合C(x,2)的算法。

注意中间要取模。

class Solution {
public:
    /**
     * @param nums: the given array
     * @param limit: the limit on the absolute difference of the subarray
     * @return: Find the number of triplet subarray with the absolute difference less than or equal to limit
     */
    int tripletSubarray(vector<int> &nums, int limit) {
        int len = nums.size();
        long long count = 0;
        int p1 = 0, p2 = 0;
        
        for (int p2 = 2; p2 < len; ++p2) {
            while(nums[p2] - nums[p1] > limit) {
                p1++;
            }
            count += ((p2 - p1) * (p2 - p1 - 1) / 2) % 99997867;
        }
        return count;
    }
};

 

<think> 根据用户的问,他遇到了在triplet x64-windows中安装软件时出现的两个错误: 1. 'Unable to find a valid Visual Studio instance' 2. 'Could not locate a complete Visual Studio instance' 引用[1]中提到错误信息:由于英语语言包不可用,排除了某些VS实例。这提示我们问可能是由于Visual Studio缺少英语语言包造成的。 解决方案: 1. 确保已安装Visual Studio,并且安装时包含了英语语言包(即使系统语言是中文,某些工具链可能要求英语包)。 2. 可以通过Visual Studio Installer来添加英语语言包。 3. 如果已经安装,可能需要修复或修改安装。 步骤: a. 打开Visual Studio Installer。 b. 找到已安装的Visual Studio版本,点击“修改”。 c. 在“语言包”选项卡中,确保“英语”被选中(如果已安装,则显示“已安装”;否则,勾选并点击右下角的“修改”进行安装)。 d. 安装完成后,重新启动命令提示符或终端,再尝试安装。 另一种可能:vcpkg可能需要指定VS实例路径。可以通过设置环境变量来指定: - 设置`VCPKG_VISUAL_STUDIO_PATH`环境变量指向VS的安装路径(例如:`C:\Program Files (x86)\Microsoft Visual Studio\2019\Community`)。 如果上述方法无效,可能需要安装完整的Visual Studio工作负载,特别是“使用C++的桌面开发”工作负载。 此外,用户可能需要运行vcpkg的环境要求:在开始使用vcpkg前,需要从开始菜单打开“适用于VS的开发者命令提示符”,或者确保普通命令提示符中已设置好VS的环境变量(通过运行vcvarsall.bat)。 最后,建议用户检查vcpkg是否最新,更新vcpkg(`git pull` 和 `.\bootstrap-vcpkg.bat`)也可能解决已知问。 相关问: 1. 如何为Visual Studio安装英语语言包? 2. 如何设置vcpkg使用特定版本的Visual Studio? 3. 如何修复vcpkg在Windows上的安装错误? </think> ### 解决"Unable to find a valid Visual Studio instance"错误的方法 此错误通常发生在使用vcpkg安装软件包时,系统无法检测到完整可用的Visual Studio实例。以下是完整的解决步骤: #### 1. **验证Visual Studio安装** - 打开Visual Studio Installer - 检查是否安装了以下必需组件: - `Desktop development with C++`(使用C++的桌面开发) - `English language pack`(英语语言包)[^1] - 若缺少英语语言包: ```powershell # PowerShell管理员权限运行 Set-WindowsDefaultLanguage -Language en-US ``` 或在VS Installer的"Language packs"选项卡中勾选English #### 2. **添加环境变量** 在系统环境变量中添加VS路径: ```powershell # 替换版本号(2019/2022) $env:VCPKG_VISUAL_STUDIO_PATH = "C:\Program Files\Microsoft Visual Studio\2022\Community" ``` #### 3. **安装Windows SDK** - 在VS Installer的"Individual components"中勾选: - `Windows 10/11 SDK` - `C++ ATL for latest v143 build tools` #### 4. **修复权限问** ```powershell # PowerShell管理员运行 Set-ExecutionPolicy RemoteSigned -Force Install-Module VSSetup -Scope CurrentUser -Force Get-VSSetupInstance | Select InstallationPath ``` #### 5. **重试安装** 完成上述步骤后: ```cmd vcpkg install <包名> --triplet=x64-windows ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值