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

news2025/1/11 23:37:21

文章目录

  • 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.coloradmin.cn/o/679940.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis【Redis数据类型(String、List、Set、Hash 、Zset)】(二)-全面详解(学习总结---从入门到深化)

目录 Redis数据类型_String set get append strlen setex setnx getrange setrange incr decr incrby/decrby key step mset mget getset Redis数据类型_List lrange lpop/rpop lindex llen lrem linsert lset Redis数据类型_Set smembers sism…

如何在 JavaScript 中处理 HTML 事件?

&#x1f482; 个人网站:【海拥】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 目录 前言什么是HTML事件Jav…

基于多进程并发-进程通讯之共享内存(shared memmory)

一、什么是共享内存 操作系统对进程内存实现原理&#xff1a; 现代操作系统&#xff0c;对于内存管理&#xff0c;采⽤的是虚拟内存技术&#xff0c;也就是每个进程都有⾃⼰独⽴的虚拟内存空间&#xff0c;不同进程的虚拟内存映射到不同的物理内存中。所以&#xff0c;即使进程…

Python交互式模式的特点和用法

Python交互式&#xff08;Interactive Mode&#xff09;是一种Python语言的工作模式&#xff0c;与传统的编写、保存、运行的方式不同&#xff0c;它允许用户直接在控制台窗口中输入和执行Python代码。 Python交互式的特点包括&#xff1a; 实时性&#xff1a;每输入一条语句&a…

黑马程序员前端 Vue3 小兔鲜电商项目——(八)登录页面

文章目录 账号密码路由配置模版代码配置路由跳转 表单校验实现校验要求代码实现统一校验 登录基础业务实现统一错误信息提示Pinia 管理用户数据Pinia 用户数据持久化用户登录状态请求拦截器携带 token退出登录实现Token 失效拦截处理 登录页面的主要功能就是表单校验和登录登出…

【Redis 基础及在 Java 中的应用】

文章目录 Redis 基础及在 Java 中的应用1 Redis 入门1.1 Redis 简介1.2 Redis 下载与安装1.3 Redis服务启动与停止 2 数据类型2.1 介绍2.2 五种常用数据类型 3 常用命令3.1 字符串 string 操作命令3.2 哈希 hash 操作命令3.3 列表 list 操作命令3.4 集合 set 操作命令3.5 有序集…

软件SPI读写W25Q64硬件SPI读写W25Q64

目录 软件SPI读写W25Q64 MySPI W25Q64 主函数 硬件SPI读写W25Q64 软件SPI读写W25Q64 程序整体框架&#xff1a; SPI模块包含通信引脚封装&#xff0c;初始化&#xff0c;SPI三个基本时序单元&#xff08;起始&#xff0c;终止&#xff0c;交换一个字节&#xff09; W2…

matlab实现语音信号的频域分析及应用

1.语音信号本质上是非平稳信号。但我们可以假设语音信号在一个短时间内是平稳的&#xff0c;这样我们用稳态分析方法处理非平稳信号。应用在傅立叶分析就是短时傅立叶变换。 语音的频域分析&#xff1a;包括语音信号的频谱、功率谱、倒频谱、频谱包络等. 常用频域分析方法&am…

排序算法之堆排序_20230624

排序算法之堆排序 前言 堆排序是基于比较排序的一类算法&#xff0c;算法重复利用堆(Binary heap)的特性&#xff0c;最大&#xff08;最小&#xff09;元素一定位于堆顶的位置&#xff0c;那么就可以提取堆顶元素&#xff0c;放置在数组的尾部位置&#xff0c;后再把剩余的元…

设计模式之状态模式笔记

设计模式之状态模式笔记 说明State(状态)目录状态模式示例类图抽象状态类环境角色类电梯开启状态类电梯关闭状态类电梯运行状态类电梯停止状态类测试类 说明 记录下学习设计模式-状态模式的写法。JDK使用版本为1.8版本。 State(状态) 意图:允许一个对象在其内部状态改变时改…

从零搭建一台基于ROS的自动驾驶车-----4.定位

系列文章目录 北科天绘 16线3维激光雷达开发教程 基于Rplidar二维雷达使用Hector_SLAM算法在ROS中建图 Nvidia Jetson Nano学习笔记–串口通信 Nvidia Jetson Nano学习笔记–使用C语言实现GPIO 输入输出 Autolabor ROS机器人教程 从零搭建一台基于ROS的自动驾驶车-----1.整体介…

【Leetcode60天带刷】day25回溯算法——216.组合总和III,17.电话号码的字母组合

​ 题目&#xff1a; 216. 组合总和 III 找出所有相加之和为 n 的 k 个数的组合&#xff0c;且满足下列条件&#xff1a; 只使用数字1到9每个数字 最多使用一次 返回 所有可能的有效组合的列表 。该列表不能包含相同的组合两次&#xff0c;组合可以以任何顺序返回。 示例 1…

读书笔记--数据治理之术

继延续上一篇文章&#xff0c;对数据治理之术进行学习思考&#xff0c;这部分内容是本书整体内容的核心细节&#xff0c;内容比较多比较杂&#xff0c;通读了好长时间才动手总结整理&#xff0c;因此更新的慢了一些。数据治理之术是操作层面的技术或方法&#xff0c;数据治理相…

linux系统如何添加硬盘设备

前言&#xff1a; 今天记录一下硬盘方面的知识&#xff0c;主要讲一下分区、挂载方面的知识&#xff0c;心情太郁闷了&#xff0c;假期的最后一天。 1、硬盘的命名规则 现在的硬盘设备一般都会以“/dev/sd”开头&#xff0c;而一台主机上可以有多块硬盘设备&#xff0c;因此系…

6.24全球央行鹰派立场重现,下周黄金是否会继续下跌?

近期有哪些消息面影响黄金走势&#xff1f;下周黄金多空该如何研判&#xff1f; ​黄金消息面解析&#xff1a;周五&#xff08;6月23日&#xff09;美市尾盘&#xff0c;现货黄金收报1920.44美元/盎司&#xff0c;上升6.58美元或0.34%&#xff0c;日内最高触及1937.46美元/盎…

Linux基础服务3——samba

文章目录 一、基本了解1.1 服务安装1.2 服务进程和端口1.3 samba用户1.4 配置文件1.4.1 主配置文件1.4.2 配置文件参数 1.5 安全级别 二、访问samba2.1 参数测试2.2 交互式访问2.3 挂载访问2.3.1 临时挂载2.3.2 永久挂载 2.4 配置用户认证共享2.5 匿名共享 一、基本了解 什么是…

VS Code基于服务器中的docker的开发环境配置

VS Code基于服务器中的docker的开发环境配置 基于Dev Containers插件基于Jump Machine&#xff08;跳板机&#xff09;服务器通过ssh连接docker容器VS Code配置ssh config文件连接docker容器 基于Dev Containers插件 当然可以在vscode中直接下载Dev Containers插件&#xff0c…

表上作业法一般流程(最小元素法、闭合回路法、位势法)

目录 一、列出物资调运平衡表和运价表 二、编制初始调运方案 三、初始方案的检验与调整 1&#xff09;闭合回路法 2&#xff09;位势法 3&#xff09;调整调运方案 表上作业法一般步骤&#xff1a; ①列出调运物资的供需(产销)平衡表及运价表&#xff1b; ②按最小元素…

mediapipe 谷歌高效ML框架-图像识别、人脸检测、人体关键点检测、手部关键点检测

参考&#xff1a; https://github.com/google/mediapipe https://developers.google.com/mediapipe/solutions/guide 框架也支持cv、nlp、audio等项目&#xff0c;速度很快&#xff1a; 1、图形识别 参考&#xff1a;https://developers.google.com/mediapipe/solutions/vi…

05.内存管理:动态申请和释放内存

动态分配内存&#xff0c;进行内存管理 参考: 伙伴算法原理简介 linux 0.11源码 本文主要针对Linux0.11的malloc和free进行分析。是一种类似伙伴系统的内存管理方法&#xff0c;不过伙伴系统的内存通常是申请大于一页的内存&#xff0c;但是在该内核版本的内存管理&#xff0c…