刷题记录:哈希 | leetcode-2352. 相等行列对 2023/6/6

news2024/12/26 23:44:09

2352. 相等行列对

这题还是非常简单的。如果用模拟的方法,时间复杂度要达到O(n^3)了,感觉不太可。

这回学聪明了,没有一上来就想着暴力模拟。用哈希的办法,可以把时间复杂度降为O(n^2)。

我的思路是先转置矩阵,再用哈希Map。基本思路就是把grid当中的每一行存到一个哈希Map里,并记录它出现的次数;然后比对转置数组tmp的每一行是否在哈希Map中出现,以及出现的次数。

我想先转置矩阵的原因是,这道题要求行和列进行比较。Java里,二维数组就是一维数组的数组,操控行就是操控一个个一维数组,直接用下标grid[i]即可。操控列我感觉不那么方便。

Java里面没有转置二维数组的库函数,要自己写一个。(刚开始我还以为Arrays里有,在里面找了半天也没找到。后来才想起来是Python的numpy库里有……)

如何把数组内容存到哈希表里?直接写Map<int[],xxxx>或Set<int[]>是不能达到目的的。注意,这样写语法上是没问题的,但是放入Map或Set中的是数组的引用,实际上存入的并不是数组的内容。因此,如果要实现把数组按照内容放入哈希中,必须自己封装一个数组并重写hashcode()方法。

其实也不复杂,可以这样:

import java.util.Arrays;

public class MyIntArray {
    private int[] array;

    public MyIntArray(int[] array) {
        this.array = array;
    }

    // Getter and setter methods...

    @Override
    public int hashCode() {
        return Arrays.hashCode(array);
    }

    // Equals method and other code...
}

MyIntArray类包装了一个整型数组。在hashCode()方法中使用Arrays.hashCode()方法来计算整型数组的哈希码。该方法会将整型数组的内容纳入计算,并返回最终的哈希码。

注意:Arrays.hashCode()方法会考虑整型数组的内容来计算哈希码。这样可以确保在只有数组的内容相同的情况下,两个MyIntArray对象的哈希码才会相等。

Arrays.hashCode()是Java中Arrays类提供的一个静态方法,用于计算数组的哈希码。它接受一个数组作为参数,并返回一个基于数组内容的哈希码。

Arrays.hashCode()方法的计算过程如下:

  1. 如果传入的数组为null,返回0作为哈希码。

  2. 如果传入的数组不为null,计算数组的哈希码。

  3. 遍历数组的每个元素,并将每个元素的哈希码进行累加或异或操作,生成最终的哈希码。

使用Arrays.hashCode()方法可以方便地计算数组的哈希码,而不需要手动编写复杂的哈希码计算逻辑。它内部使用了与Java的Object.hashCode()方法类似的算法,确保在只有数组的内容相同的情况下,不同的数组会生成不同的哈希码。

需要注意的是,Arrays.hashCode()方法只计算数组的内容,而不考虑数组的引用地址。这意味着如果两个数组具有相同的内容,即使它们在内存中的位置不同,它们的哈希码也会相等。

由于hashcode是native方法,没法直接在idea中查看到它的源码。不过记住这个结论就好了。

我实现的时候其实没有用到上面的这些O(∩_∩)O

我通过自定义arrayToString()方法,把数组的内容转换成字符串,然后对字符串进行哈希操作。String是重写过hashcode()方法的,所以没有上述问题。

为什么用Map不用Set?原因很简单,因为原数组grid当中可能存在内容相同的行。如果用哈希Set,那么它们会被去重。比如原数组中有两行都是2 2 7 1,转置数组tmp中也有一行是2 2 7 1.那么原本应该记录结果为2,但由于Set去重了原数组中的两相同行,最终结果会变成1.

    String arrayToString(int[] array) {
        String ret = "";
        for (int j : array) {
            ret += j + " ";
        }
        return ret;
    }

注意,ret += j + " " 这一句里,后面的这个空格拼接非常重要。看看输入这个样例的情况就知道了:

[[11,1],[1,11]]

Java里的Arrays.toString转换后是格式化的字符串,其实也是可以的。因为这里这个分隔符并不影响。

不过,要想没有分隔符,也是可以的,可以这样:

import java.util.Arrays;
import java.util.stream.Collectors;

int[] arr = {1, 2, 3, 4, 5};
String arrString = Arrays.stream(arr)
                        .mapToObj(String::valueOf)
                        .collect(Collectors.joining());

System.out.println(arrString);  // 输出:12345

(不过这道题似乎就没有这个必要背这个了……)

我提交的代码是这,是通过的: 

class Solution {
    String arrayToString(int[] array) {
        int n = array.length;
        String ret = "";
        for (int j : array) {
            ret += j + " ";
        }
        return ret;
    }
    public int equalPairs(int[][] grid) {
        int n = grid.length;

        int[][] tmp = new int[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                tmp[i][j] = grid[j][i];
            }
        }

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                System.out.print(grid[i][j] + " ");
            }
            System.out.println();
        }
        System.out.println("-----");
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                System.out.print(tmp[i][j] + " ");
            }
            System.out.println();
        }
        int count = 0;
        Map<String, Integer> map = new HashMap<>();

        for (int i = 0; i < n; i++) {
            String str = arrayToString(grid[i]);
            map.put(str, map.getOrDefault(str, 0)+1);
        }

        int j = 0;
        while(j < n) {
            String str = arrayToString(tmp[j]);
            if(map.containsKey(str)) {
                count += map.get(str);
            }
            j++;
        }

        return count;
    }
}

今天还刷了二分:162. 寻找峰值

class Solution {
    int bin(int[] nums, int l, int r) {
        if(l == r) {
            return l;
        }
        l = 1;
        r = nums.length-2;
        while(l < r) {
            int mid = (l+r+1)>>1;
            if(nums[mid] > nums[mid+1] && nums[mid] > nums[mid-1]) {
                return mid;
            }else if(nums[mid] < nums[mid+1]){
                l = mid;
            }else if(nums[mid] > nums[mid+1]){
                r = mid-1;
            }
        }
        return l;
    }
    public int findPeakElement(int[] nums) {
        if(nums.length == 1) {
            return 0;
        }
        int ret = bin(nums, 1, nums.length-2);
        if(nums[0] > nums[1])   ret = 0;
        if(nums[nums.length - 1] > nums[nums.length - 2])   ret = nums.length - 1;
        return ret;
    }
}

巩固一下模板:

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/615007.html

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

相关文章

Matlab论文插图绘制模板第99期—正负柱状图

在之前的文章中&#xff0c;分享了很多Matlab柱状图的绘制模板&#xff1a; 进一步&#xff0c;再来分享一种特殊的柱状图&#xff1a;正负柱状图。 先来看一下成品效果&#xff1a; 特别提示&#xff1a;本期内容『数据代码』已上传资源群中&#xff0c;加群的朋友请自行下载…

HTML+JS 实现手机号码归属地查询功能

手机号码归属地 API 是一种提供号码归属地信息的接口&#xff0c;它通过与运营商和电信数据库交互&#xff0c;根据手机号码查询相关归属地信息并返回结果。通过使用手机号码归属地API&#xff0c;开发者可以轻松地集成号码归属地查询功能到他们的应用程序和服务中&#xff0c;…

简介- 谷粒商城项目微服务架构图

目录 项目前置知识一、前后端分离开发&#xff0c;分为 内网部署 和 外网部署。二、用户是通过使用 客户端 来完成各种的功能三、网关的作用四、Sentiel组件五、Feign组件六、OAuth2.0认证中心七、SpringSecurity组件八、关于数据存储的解决方案九、定位bug十、注册中心十一、配…

Java 进阶 -- Lambda 表达式

Lambda Expressions 匿名类&#xff08;anonymous classes&#xff09;的一个问题是&#xff0c;如果匿名类的实现非常简单&#xff0c;比如一个只包含一个方法的接口&#xff0c;那么匿名类的语法可能会显得笨拙和不清晰。在这些情况下&#xff0c;您通常试图将功能作为参数传…

Spark RDD计算总分与平均分

文章目录 一&#xff0c;提出任务二&#xff0c;实现思路三&#xff0c;准备工作1、启动HDFS服务2、启动Spark服务3、在本地创建成绩文件4、将成绩文件上传到HDFS 四&#xff0c;完成任务1、在Spark Shell里完成任务&#xff08;1&#xff09;读取成绩文件&#xff0c;生成RDD&…

从Java BIO到NIO再到多路复用,看这篇就够了

从一次优化说起 近期优化了一个老的网关系统&#xff0c;在dubbo调用接口rt1000ms时吞吐量提升了25倍&#xff0c;而线程数却由64改到8。其他的优化手段不做展开&#xff0c;比较有意思的是为什么线程数减少&#xff0c;吞吐量却可以大幅提升&#xff1f;这就得从IO模型说起&a…

消息队列kafka使用技巧和常见问题

目录 【消息队列概述】 【kafka】 消息丢失问题 消息重复问题 消费顺序问题 消息积压问题 kafka集群部署 【消息队列概述】 消息队列主要解决应用耦合、异步消息、流量削锋等问题&#xff0c;是大型分布式系统不可缺少的中间件。消息生产者 只管把消息发布到 MQ 中而不…

【CMake 入门与进阶(4)】 CMakeLists.txt 语法规则基础及部分常用指令-续(附使用代码)

由于篇幅问题本篇接着上文继续介绍 CMakeLists.txt 语法规则基础及常用指令。 aux_source_directory aux_source_directory 命令会查找目录中的所有源文件&#xff0c;其命令定义如下&#xff1a; aux_source_directory(<dir> <variable>)从指定的目录中查找所有…

开发者工具调试

Console控制台 F12打开控制台 选择其他tab面板时&#xff0c;ESC打开Console面板enter直接执行Console的代码&#xff0c;shiftEnter输入多行代码 Source面板 左键单机行号设置断点&#xff0c;或在代码中添加debugger;右键单机行号设置条件断点&#xff08;条件表达式为tr…

PowerShell install 一键部署mariadb10.11

mariadb MariaDB数据库管理系统是MySQL的一个分支&#xff0c;主要由开源社区在维护&#xff0c;采用GPL授权许可 MariaDB的目的是完全兼容MySQL&#xff0c;包括API和命令行&#xff0c;使之能轻松成为MySQL的代替品。在存储引擎方面&#xff0c;使用XtraDB来代替MySQL的Inno…

ChatGPT 国内镜像网站大全(含GPT-4.0版本)之什么年代还在写传统文章。

前言&#xff1a; 临近期末&#xff0c;大量水课的节课作业都是论文&#xff0c;一篇就是几千字&#xff0c;这对于还要复习专业课的我们可以说是压力巨大&#xff1a;心理健康论文&#xff0c;安全教育论文&#xff0c;大学语文论文&#xff0c;书法赏析论文&#xff0c;劳动…

小议C++函数签名与模板返回类型

题记&#xff1a;什么事情都要追问一个为什么&#xff0c;真正理解了为什么&#xff0c;才能活学活用。 代码1 下面的代码能编译通过吗&#xff1f; #include <stdio.h> #include <stdlib.h>class X { public:int *get() { return new int(); }double *get() { r…

MATLAB矩阵的分解函数与案例举例

系列文章目录 MATLAB当中线性方程组、不定方程组、奇异方程组、超定方程组的介绍 MATLAB语句实现方阵性质的验证 MATLAB绘图函数的相关介绍——海底测量、二维与三维图形绘制​​​​​​ MATLAB求函数极限的简单介绍 文章目录 前言 1. 奇异值分解&#xff08;SVD&#x…

C++类和对象-4

在上篇C类和对象的博客中&#xff0c;我们讲述了析构函数、拷贝构造函数、浅拷贝和深拷贝的内容&#xff0c;我们紧接上文&#xff0c;开始讲述接下来的文章。 目录 1.this指针 1.1引入 1.2内容 1.3特征 1.4用法 2.静态成员 2.1内容 2.2静态数据成员 2.3静态成员函数…

Vue.js 中的国际化支持是什么?如何进行国际化支持?

Vue.js 中的国际化支持是什么&#xff1f;如何进行国际化支持&#xff1f; Vue.js 是一款流行的前端框架&#xff0c;它提供了许多方便的工具和 API&#xff0c;用于构建交互式的用户界面。其中&#xff0c;国际化支持是 Vue.js 中重要的一部分&#xff0c;它可以让我们轻松地…

如何强制删除文件夹?这样操作就能搞定!

案例&#xff1a;我想删掉一些没有用的文件夹&#xff0c;释放一些电脑内存&#xff0c;但是我发现&#xff0c;有些文件夹并不能直接被删除。怎样才能删除这些文件夹&#xff1f;有没有小伙伴有解决的办法。 在使用电脑过程中&#xff0c;我们可能会遇到一些无法正常删除文件夹…

空间计算时代来临:苹果Vision Pro震撼上市,探索真实与虚拟的新边界

目录 前言Vision Pro的外观设计Vision Pro的交互方式Vision Pro 硬件配置Vision Pro 上市时间及销售价格Vision Pro与传统XR设备不同点总结其它资料下载 前言 苹果公司在2023年6月6日的WWDC23主题演讲中正式发布了传闻已久的头显产品——Vision Pro。WWDC&#xff0c;全称为“…

LLM Accelerator:使用参考文本无损加速大语言模型推理

编者按&#xff1a;如今&#xff0c;基础大模型正在诸多应用中发挥着日益重要的作用。大多数大语言模型的训练都是采取自回归的方式进行生成&#xff0c;虽然自回归模型生成的文本质量有所保证&#xff0c;但却导致了高昂的推理成本和长时间的延迟。由于大模型的参数量巨大、推…

被App包围 苹果Vision Pro将你推入空间“大屏”

2小时&#xff0c;这是2023年苹果开发者大会&#xff08;WWDC&#xff09;首日发布会的直播总时长&#xff0c;仅YouTube上&#xff0c;就有483.9万次观看。发布会开启时&#xff0c;北京时间是6月6日凌晨1点&#xff0c;众多科技博主串流直播了这场发布会。 苹果CEO蒂姆库克引…

3.2 继续完善的Vue.js响应式系统

前文提要&#xff1a; 3.0 响应式系统的设计与实现 3.1 一个稍微完善的Vue.js响应式系统 1、解决副作用函数的死循环问题 在解决了分支的切换的问题&#xff0c;此时还有一个代码死循环的问题&#xff0c;其这个死循环很容易触发&#xff0c;如下代码&#xff1a; const dat…