当前位置: 首页 > article >正文

给定差值的组合

一、题目

给定差值的组合
给定一个数组,每个元素的值是唯一的,找出其中两个元素相减等于给定差值 diff 的所有不同组合的个数。
组合是无序的:如:(1, 4)和(4, 1)表示的是同一个组合。
输入
第一个参数为 diff,-50000 <= diff <= 50000
第二个参数为数组 numbers,2 <= numbers.length <= 102400, -20 <= numbers[i] <= 102400
输出
1个整数,表示满足要求的不同组合的个数

样例1
复制输入:
3
[1, 3, 2, 5, 4]
复制输出:
2
解释:
差值 diff 为 3,其中 4 - 1 = 3,5 - 2 = 3,共 2 个组合满足条件,因此输出 2

样例2
复制输入:
-1
[1, 2, 3]
复制输出:
2
解释:
其中 1 - 2 = -1,2 - 3 = -1,共 2 个组合满足条件,因此输出 2。

代码框架

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include "securec.h"
#include "solution.c"

// 以下为考题输入输出框架,此部分代码不建议改动;提交代码时请勿包含下面代码
static int *ExpandListInt(int *ptr, size_t oldLen, size_t newLen)
{
    int *newPtr = (int *)malloc(newLen * sizeof(*ptr));
    if (newPtr) {
        for (size_t i = 0; i < oldLen; ++i) {
            newPtr[i] = ptr[i];
        }
    }
    if (ptr) { free(ptr); }
    return newPtr;
}

static void SkipWs(void)
{
    char c = (char)getchar();
    while (c == ' ' || c == '\r' || c == '\n') {
        c = (char)getchar();
    }
    (void)ungetc(c, stdin);
}

static void FreeListInt(int *value)
{
    if (!value) { return; }
    free(value);
}

static bool ReadListInt(int **value, size_t *size)
{
    SkipWs();
    char c = (char)getchar();
    if (c != '[') { return false; }

    SkipWs();
    c = (char)getchar();
    if (c == ']') {
        *value = NULL;
        *size = 0;
        return true;
    }
    (void)ungetc(c, stdin);

    size_t cap = 32;
    for (size_t pos = 0;; ++pos) {
        if (pos == 0 || pos >= cap) {
            cap *= 2;
            *value = ExpandListInt(*value, pos, cap);
            if (*value == NULL) { break; }
        }
        if (scanf_s("%d", &(*value)[pos]) != 1) { break; }

        SkipWs();
        int in = getchar();
        if (in == EOF) { break; }
        if ((char)in == ']') {
            *size = pos + 1;
            return true;
        }
        if ((char)in != ',') { break; }
    }

    FreeListInt(*value);
    *value = NULL;
    return false;
}

int main(void)
{
    int diff = 0;
    int *numbers = NULL;
    size_t numbersSize = 0;
    int returnValue = 0;
    bool isOk = false;

    do {
        if (scanf_s("%d", &diff) != 1) { break; }
        if (!ReadListInt(&numbers, &numbersSize)) { break; }
        isOk = true;
        returnValue = GetDiffCnt(diff, numbers, numbersSize);
        printf("%d", returnValue);
    } while (false);

    if (!isOk) { printf("Error: Input format incorrect!"); }
    FreeListInt(numbers);
    numbers = NULL;

    return 0;
}

二、解题

方法一

两层for循环

static int GetDiffCnt2(int diff, const int* numbers, size_t numbersSize)
{
    int count = 0;
    for (int i = 0; i < numbersSize; i++) {
        for (int j = i + 1; j < numbersSize; j++) {
            if (numbers[i] - numbers[j] == diff || numbers[j] - numbers[i] == diff) {
                count++;
            }
        }
    }
    return count;
}

方法二

快慢指针

static int compareUpper(const void* a, const void* b)
{
    return *(int*) a - *(int*) b;
}

static int compareLower(const void* a, const void* b)
{
    return *(int*) b - *(int*) a;
}

static int GetDiffCnt(int diff, const int* numbers, size_t numbersSize)
{
    int count = 0;
    bool upperFlag = false;
    if (diff >= 0) {
        qsort(numbers, numbersSize, sizeof(int), compareUpper);
        upperFlag = true;
    } else {
        qsort(numbers, numbersSize, sizeof(int), compareLower);
    }

    int num[510];
    memcpy_s(num, 510 * sizeof(int), numbers, 510 * sizeof(int));

    int slow = 0;
    int fast = slow + 1;
    while (slow < fast && fast < numbersSize) {
        if (numbers[fast] - numbers[slow] == diff) {
            count++;
            slow++;
            fast++;
        } else if (numbers[fast] - numbers[slow] > diff) {
            if (upperFlag) {
                slow++;
            } else {
                fast++;
            }
        } else if (numbers[fast] - numbers[slow] < diff) {
            if (upperFlag) {
                fast++;
            } else {
                slow++;
            }
        }
    }

    return count;
}

上述两个方法都可以通过下述样例


http://www.kler.cn/a/488471.html

相关文章:

  • Linux之线程池与单例模式
  • Vue3+Element给表单设置多个验证+规则Rules自定义
  • IP 地址与蜜罐技术
  • Typescript使用指南
  • DuckDB:PRAGMA语句动态配置数据库行为
  • QPS和TPS 的区别是什么?QPS 大了会有什么问题,怎么解决?
  • day03-前端Web-Vue3.0基础
  • 面向对象分析与设计Python版 面向对象分析方法
  • 机器学习:一元线性回归
  • Python基于jieba和wordcloud绘制词云图
  • gateway在eureka注册报java.lang.IndexOutOfBoundsException
  • Qt监控系统远程网络登录/请求设备列表/服务器查看实时流/回放视频/验证码请求
  • 基于Spring Boot的宠物健康顾问系统的设计与实现(LW+源码+讲解)
  • 国产编辑器EverEdit - 扩展脚本:关闭所有未修改文档
  • Docker Desktop的使用方法
  • 什么是Transformer模型中的KV缓存:上下文新增那之前计算的KV还可用,在原有基础上对新增的进行计算就行
  • opencv 学习(3)
  • js代理模式
  • 用c实现C++类(八股)
  • 【网络云SRE运维开发】2025第2周-每日【2025/01/09】小测-【第9章 VRRP原理及基本配置考试】理论和实操
  • UniAPP和Vue3生命周期hook
  • 【计算机网络】课程 实验二 交换机基本配置和VLAN 间路由实现
  • mysql和redis的最大连接数
  • Linux之线程池与单例模式
  • GPT-1模型详解及代码复现
  • 利用Python爬虫获取义乌购店铺所有商品列表:技术探索与实践