【每日算法 数据结构(C++)】—— 01 | 平方值去重统计(解题思路STL法,双指针法、流程图、代码片段)

news/2024/5/19 0:28:18 标签: 数据结构, 算法, c++, 流程图

文章目录

  • 01 | 👑 题目描述
  • 02 | 🔋 解题思路
    • STL法
    • 双指针法
  • 03 | 🧢 代码片段
    • STL法
    • 双指针法

在这里插入图片描述

“Success is not final, failure is not fatal: It is the courage to continue that counts.” - Winston Churchill

(成功并非终点,失败并非致命:真正重要的是继续前行的勇气 - 温斯顿·丘吉尔)

01 | 👑 题目描述

给你一个整数数组,数组中的数可以是正数、负数、零,请实现一个函数,返回这个数组中所有数的平方值中有多少种不同的取值

对于这个题目的理解是,给定一个整数数组,我们需要找出数组中所有数的平方值中有多少种不同的取值。换句话说,我们需要统计数组中平方值的不同取值的数量。

02 | 🔋 解题思路

STL法

为了解决这个问题,我们可以使用一个集合(Set)来存储平方值的不同取值。我们遍历整数数组中的每个数,并计算其平方值。然后,将平方值添加到集合中。由于集合的特性是不允许重复元素,所以它只会保存不同的平方值。最后,我们返回集合的大小,即不同平方值的数量。

例如,对于输入数组 [1, 2, -3, 2, 0, -1, 3],经过计算得到的平方值数组是 [1, 4, 9, 4, 0, 1, 9]。将这些平方值添加到集合中,得到的集合是 {0, 1, 4, 9},其中有4个不同的平方值。因此,最终结果就是 4。

这样的解题思路可以确保我们只计算不同平方值的数量,而不会重复计算相同的平方值。

  • 具体解题思路如下

    1. 创建一个空集合(set)来存储平方值的不同取值。

    2. 遍历整数数组中的每个数。

    3. 对于每个数,计算其平方值。

    4. 将平方值添加到集合中。由于集合的特性是不允许重复元素,所以只会保存不同的平方值。

    5. 最后,返回集合的大小,即不同平方值的数量。

  • 流程概括如下

    1. 创建一个空的集合,用来存储不同平方值。

    2. 遍历整数数组中的每个数。

      a. 计算当前数的平方值。

      b. 将平方值添加到集合中。

    3. 返回集合的大小,即不同平方值的数量。

在这里插入图片描述

  • 时间 && 空间复杂度
    • 时间复杂度
      遍历数组并计算每个数的平方值需要 O(n) 的时间复杂度,其中 n 是数组的长度。
      添加平方值到集合中的操作需要 O(1) 的时间复杂度。
      因此,整个算法时间复杂度为 O(n)
    • 空间复杂度
      创建了一个集合 uniqueSquares 来存储不同的平方值。
      平方值的数量最多为数组的长度 n,所以集合 uniqueSquares 的大小最大为 n。
      因此,整个算法空间复杂度为 O(n)

双指针法

参考STL法的思路,只要保证返回结果中的平方值都是唯一的即可,那么就可以采用排序和双指针法进行解题。

  • 具体的解题流程

    1. 对整数数组进行排序;

    2. 创建一个变量 count,初始值为 0。

    3. 设置两个指针,left 指向数组的开头,right 指向数组的末尾。

    4. 当 left <= right 时,执行以下步骤:

      a. 计算指针 left 指向的数的平方值 squareLeft。

      b. 计算指针 right 指向的数的平方值 squareRight。

      c. 如果 squareLeft 等于 squareRight,表示找到了一个新的平方值,将 count 加 1,并同时将 left 和 right 向内缩小一个位置。

      d. 如果 squareLeft 大于 squareRight,说明 left 指向的数的平方值较大,将 count 加 1,并将 left 向内缩小一个位置。

      e. 如果 squareLeft 小于 squareRight,说明 right 指向的数的平方值较大,将 count 加 1,并将 right 向内缩小一个位置。

    5. 返回 count,即不同平方值的数量。

在这里插入图片描述

  • 时间 && 空间复杂度
    • 时间复杂度
      对整数数组进行排序的时间复杂度为 O(n log n),其中 n 是数组的长度。
      然后,使用双指针遍历数组的过程最多需要 O(n) 的时间复杂度,其中 n 是数组的长度。
      因此,整个算法时间复杂度为 O(n log n)
    • 空间复杂度
      排序算法通常需要使用 O(log n) 的额外空间,其中 n 是数组的长度。因此,排序过程的空间复杂度为 O(log n)。
      除了排序过程,只使用了常量级别的额外空间来存储变量和指针。
      因此,整个算法空间复杂度为 O(log n)

03 | 🧢 代码片段

STL法

#include <iostream>
#include <vector>
#include <unordered_set>

int countUniqueSquares(std::vector<int>& arr) {
    std::unordered_set<int> squares; // 创建一个空集合来存储平方值的不同取值

    for (int num : arr) {
        int square = num * num; // 计算平方值
        squares.insert(square); // 将平方值添加到集合中
    }

    return squares.size(); // 返回集合的大小,即不同平方值的数量
}

int main() {
    // 测试样例
    std::vector<int> arr = {-4, -2, -1, 0, 1, 3, 5};
    int result = countUniqueSquares(arr);
    std::cout << "(STL法)不同平方值的数量为: " << result << std::endl;
    
    return 0;
}

在这里插入图片描述

双指针法

#include <iostream>
#include <vector>
#include <algorithm>

int countUniqueSquares(std::vector<int>& arr) {
    // 对数组进行排序,按照绝对值的大小进行排序
    std::sort(arr.begin(), arr.end(), [](int a, int b) {
        return std::abs(a) < std::abs(b);
    });

    int count = 0; // 记录不同平方值的数量

    int left = 0; // 左指针
    int right = arr.size() - 1; // 右指针

    while (left <= right) {
        if (arr[left] >= 0) {
            // 计算平方值,并将右指针往左移动
            count++;
            right--;
        } else if (arr[right] < 0) {
            // 计算平方值,并将左指针往右移动
            count++;
            left++;
        } else {
            // arr[left] < 0 且 arr[right] >= 0,比较平方值,根据大小移动指针
            if (arr[left] * arr[left] != arr[right] * arr[right]) {
                count++;
            }
            left++;
            right--;
        }
    }

    return count;
}

int main() {
    std::vector<int> arr = {-4, -2, -1, 0, 1, 3, 5};
    int result = countUniqueSquares(arr);
    std::cout << "(双指针发)不同平方值的数量为: " << result << std::endl;
    
    return 0;
}

在这里插入图片描述

在这里插入图片描述

各位大佬点点关注,点赞,收藏,有空的时候再回来看看,谢谢

http://www.niftyadmin.cn/n/463237.html

相关文章

Qt/C++编写手机版本视频播放器和Onvif工具(可云台和录像)

一、前言 用Qtffmpeg写播放器很多人有疑问&#xff0c;为何不用Qt自己的多媒体框架来写&#xff0c;最重要的原因是Qt自带的目前都依赖具体的本地解码器&#xff0c;如果解码器不支持&#xff0c;那就是歇菜的&#xff0c;最多支持个MP4格式&#xff0c;而且在手机上也都是支持…

C++ 笔记 22 (STL常用算法 - 排序 拷贝 替换)

五. STL-常用算法 3. 常用排序算法 sort //对容器内元素进行排序 random_shuffle //洗牌&#xff0c;指定范围内的元素随机调整次序 merge //容器元素合并&#xff0c;并储存到另一容器中 reverse //反转指定范围的元素3.1 sort 功能&#xff1a;对容器内元素进行排序 …

多线程编程和并行计算的实例:期货交易及打车软件算法

多线程编程和并行计算的实例:期货交易及打车软件算法 解决现实生活中的问题时&#xff0c;多处理器和多核系统的普及使并行计算成为一个关键的性能提升手段。在这篇博客中&#xff0c;我们将通过深入讨论两个引人入胜而又具有实际意义的场景——期货交易和打车匹配算法&#xf…

【C++核心】指针和引用案例详解

文章目录 一. 指针1.1 指针的基本概念1.2 指针变量的定义和使用1.3 指针所占内存空间1.4 空指针和野指针1.5 const修饰指针1.6 指针和数组1.7 指针和函数1.8 指针、数组、函数 二. 引用2.1 引用的基本使用2.2 引用注意事项2.3 引用做函数参数2.4 引用做函数返回值2.5 引用的本质…

C语言里面那些你必须知道的常用关键字(详细讲解)

前言 哈喽&#xff0c;各位铁汁们好啊&#xff01;✨今天来给大家带来的是C语言中我们常用的关键字静态static的详细讲解和typedef 、#define定义常量和宏。   既然是详解想必大家必定是想学一些平常学不到的东西吧&#xff01;这里博主给大家详细讲解static修饰的变量在内存…

Linux tracing之基于uprobe/kprobe的调试调优浅析

经过长期的发展, kprobes/uprobes 机制在事件(events)的基础上分别为内核态和用户态提供了追踪调试的功能, 这也构成了 tracepoint 机制的基础, 后期的很多工具, 比如 perf_events, ftrace 等都是在其基础上演化而来. 参考由 Brendan Gregg 提供的资料来看, kprobes/uprobes 在…

MATLAB实现有导师学习神经网络算法(附上完整仿真源码+数据)

有导师学习神经网络算法是一种常用的机器学习算法&#xff0c;它可以通过训练数据集来学习输入和输出之间的映射关系&#xff0c;从而实现分类和回归任务。MATLAB作为一种功能强大的科学计算软件&#xff0c;提供了丰富的工具和函数&#xff0c;可以帮助我们轻松实现有导师学习…

【网络2】MII MDC/MDIO

文章目录 1.MII&#xff1a;ISO网络模型中物理层&#xff08;phy&#xff09;和数据链路层&#xff08;mac&#xff09;属于硬件&#xff0c;其余都属于软件kernel2.MDC/MDIO&#xff1a;不仅管phy&#xff0c;只要支持mdio协议都可以管2.1 BMC速率适配&#xff1a;phy和switch…