力扣:49. 字母异位词分组

知识点:

散列函数

散列函数能使对一个数据序列的访问过程更加迅速有效,通过散列函数,数据元素将被更快地定位:

  1. 直接寻址法:取关键字或关键字的某个线性函数值为散列地址。即H(key)=key或H(key) = a*key + b,其中a和b为常数(这种散列函数叫做自身函数)

  2. 数字分析法:分析一组数据,比如一组员工的出生年月日,这时我们发现出生年月日的前几位数字大体相同,这样的话,出现冲突的几率就会很大,但是我们发现年月日的后几位表示月份和具体日期的数字差别很大,如果用后面的数字来构成散列地址,则冲突的几率会明显降低。因此数字分析法就是找出数字的规律,尽可能利用这些数据来构造冲突几率较低的散列地址。

  3. 平方取中法:取关键字平方后的中间几位作为散列地址。

  4. 折叠法:将关键字分割成位数相同的几部分,最后一部分位数可以不同,然后取这几部分的叠加和(去除进位)作为散列地址。通常针对较长的关键字。

  5. 随机数法:选择一随机函数,取关键字的随机值作为散列地址,通常用于关键字长度不同的场合。

  6. 除留余数法:取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址。即 H(key) = key MOD p, p<=m。不仅可以对关键字直接取模,也可在折叠、平方取中等运算之后取模。对p的选择很重要,一般取素数或m,若p选的不好,容易产生同义词。

查找效率

查找过程中,关键码的比较次数,取决于产生冲突的多少,产生的冲突少,查找效率就高,产生的冲突多,查找效率就低。因此,影响产生冲突多少的因素,也就是影响查找效率的因素。影响产生冲突多少有以下三个因素:

  1. 散列函数是否均匀;

  2. 处理冲突的方法;

  3. 散列表的装填因子。

  散列表的装填因子定义为:α= 填入表中的元素个数 / 散列表的长度

  α是散列表装满程度的标志因子。由于表长是定值,α与“填入表中的元素个数”成正比,所以,α越大,填入表中的元素较多,产生冲突的可能性就越大;α越小,填入表中的元素较少,产生冲突的可能性就越小。

  实际上,散列表的平均查找长度是装填因子α的函数,只是不同处理冲突的方法有不同的函数。

加法哈希:

常用于字符串,将字符串中的每个字符转换为其对应的 ASCII 值,然后进行加法运算来生成哈希值。

int hash(char* str) {int hashValue = 0;for (int i = 0; str[i] != '\0'; i++) {hashValue += str[i];}return hashValue;
}

这里使用了一个简单的散列函数,它是一个基于质数的乘法散列函数。具体来说,散列函数的实现如下:

//对字符串进行哈希
int hash(char* str) {int hashValue = 0;for (int i = 0; str[i] != '\0'; i++) {hashValue = (hashValue * PRIME + str[i]) % 1000007;}return hashValue;
}

在这里,PRIME 是一个选择的质数,它有助于减少碰撞。我们遍历字符串的每个字符,并用它们更新 hashValue。由于我们对 hashValue 取模 1000007,所以返回的散列值会在 01000006 之间。

位运算哈希:

先移位,然后再进行各种位运算是这种类型Hash函数的主要特点。

int bitHash(char* str) {int hashValue = 0;for (int i = 0; str[i] != '\0'; i++) {hashValue = (hashValue << 5) + str[i] ^ hashValue;}return hashValue;
}

乘法哈希:

利用了乘法的不相关性(乘法的这种性质,最有名的莫过于平方取头尾的随机数生成算法,虽然这种算法效果并不好)。

FNV(Fowler–Noll–Vo)哈希算法是一个著名的乘法哈希算法,常用于字符串哈希。它是一种非常简单但效果很好的哈希算法。

#include <stdint.h>uint32_t fnv1a(char* str) {uint32_t hash = 2166136261u; // FNV偏移基础值while (*str) {hash ^= (unsigned char)*str++;hash *= 16777619u; // FNV素数}return hash;
}

字符串操作:

#include<string.h>

字符串复制

strdup 是一个 C 语言函数,用于复制一个字符串。

strdup 函数会分配足够的内存来存储传入的字符串,并将原始字符串复制到新分配的内存中。然后返回指向新分配的字符串的指针。

char* copy = strdup(str);

free(copy);

strdup 可以用于创建字符串的副本,以便稍后使用和修改,而不影响原始字符串。

将malloc和赋值操作合二为一

排序:

void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));

  • base:指向要排序的数组的指针。
  • nmemb:数组中元素的数量。
  • size:数组中每个元素的大小(以字节为单位)。
  • compar:用于比较两个元素的函数的指针。
int compare(const void* a, const void* b) {return *(char*)a - *(char*)b;
}
 char* str1 = strdup(strs[i]);int len = strlen(str1);//对 str1 中的字符进行排序,这样,具有相同字符的异位词会有相同的排序后的字符串。qsort(str1, len, sizeof(char), compare);

暴力求解:

超出时间限制。

*returnSize记录最终数组有多少个。

returnColumnSize记录最终数组中,每个数组的长度。一维数组。

        result[*returnSize] = (char**)malloc(strsSize * sizeof(char*));

        (*returnColumnSizes)[*returnSize] = 0;

        result[*returnSize][(*returnColumnSizes)[*returnSize]] = strs[i];

        (*returnColumnSizes)[*returnSize] += 1;

/*** Return an array of arrays of size *returnSize.* The sizes of the arrays are returned as *returnColumnSizes array.* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int compare(const void* a, const void* b) {return *(char*)a - *(char*)b;
}char*** groupAnagrams(char** strs, int strsSize, int* returnSize, int** returnColumnSizes) {//记录strs中哪个词被找过了int* countstrs = (int*)malloc(strsSize * sizeof(int));//全置为0memset(countstrs, 0, strsSize * sizeof(int));*returnSize = 0;char*** result = (char***)malloc(strsSize * sizeof(char**));*returnColumnSizes = (int*)malloc(strsSize * sizeof(int));for (int i = strsSize-1; i >=0; i--) {if (countstrs[i] == 1) continue;char* str1 = strdup(strs[i]);int len = strlen(str1);//对 str1 中的字符进行排序,这样,具有相同字符的异位词会有相同的排序后的字符串。qsort(str1, len, sizeof(char), compare);result[*returnSize] = (char**)malloc(strsSize * sizeof(char*));(*returnColumnSizes)[*returnSize] = 0;result[*returnSize][(*returnColumnSizes)[*returnSize]] = strs[i];(*returnColumnSizes)[*returnSize] += 1;countstrs[i] = 1;for (int z = i-1; z >=0; z--) {if (countstrs[z] == 1) continue;char* str2 = strdup(strs[z]);if (len != strlen(str2)) {free(str2);continue;}qsort(str2, len, sizeof(char), compare);//现在都顺序排列了int flag=0;for (int j = 0; j < len; j++) {if (str1[j] == str2[j] ) {flag++;}elsebreak;}if (flag==len) {result[*returnSize][(*returnColumnSizes)[*returnSize]] = strs[z];(*returnColumnSizes)[*returnSize] += 1;countstrs[z] = 1;}free(str2);}*returnSize += 1;free(str1);}free(countstrs);return result;
}

哈希:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define PRIME 31typedef struct Node {char* key;char** values;int count;struct Node* next;
} Node;int compare(const void* a, const void* b) {return *(char*)a - *(char*)b;
}//对字符串进行哈希
int hash(char* str) {int hashValue = 0;for (int i = 0; str[i] != '\0'; i++) {hashValue = (hashValue * PRIME + str[i]) % 1000007;}return hashValue;
}Node* createNode(char* key, char* value) {Node* newNode = (Node*)malloc(sizeof(Node));newNode->key = strdup(key);newNode->values = (char**)malloc(1000 * sizeof(char*));newNode->values[0] = strdup(value);newNode->count = 1;newNode->next = NULL;return newNode;
}Node** createHashMap(int size) {Node** table = (Node**)malloc(size * sizeof(Node*));for (int i = 0; i < size; i++) {table[i] = NULL;}return table;
}void insert(Node** table, char* key, char* value, int size) {int index = hash(key) % size;if (table[index] == NULL) {table[index] = createNode(key, value);return;}Node* current = table[index];while (current->next != NULL) {if (strcmp(current->key, key) == 0) {current->values[current->count++] = strdup(value);return;}current = current->next;}if (strcmp(current->key, key) == 0) {current->values[current->count++] = strdup(value);} else {current->next = createNode(key, value);}
}char*** groupAnagrams(char** strs, int strsSize, int* returnSize, int** returnColumnSizes) {*returnSize = 0;Node** hashMap = createHashMap(1000007);*returnColumnSizes = (int*)malloc(strsSize * sizeof(int));char*** result = (char***)malloc(strsSize * sizeof(char**));for (int i = 0; i < strsSize; i++) {char* sortedStr = strdup(strs[i]);qsort(sortedStr, strlen(sortedStr), sizeof(char), compare);insert(hashMap, sortedStr, strs[i], 1000007);free(sortedStr);}for (int i = 0; i < 1000007; i++) {Node* current = hashMap[i];while (current != NULL) {result[*returnSize] = (char**)malloc(current->count * sizeof(char*));for (int j = 0; j < current->count; j++) {result[*returnSize][j] = strdup(current->values[j]);}(*returnColumnSizes)[*returnSize] = current->count;(*returnSize)++;current = current->next;}}for (int i = 0; i < 1000007; i++) {Node* current = hashMap[i];while (current != NULL) {for (int j = 0; j < current->count; j++) {free(current->values[j]);}free(current->values);Node* temp = current;current = current->next;free(temp->key);free(temp);}}free(hashMap);return result;
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机网络 Cisco路由器基本配置

一、实验内容 1、按照下表配置好PC机IP地址和路由器端口IP地址 2、配置好路由器特权密文密码“abcd&#xff0b;两位班内序号”和远程登录密码“star” 3、验证测试 a.验证各个接口的IP地址是否正确配置和开启 b.PC1 和 PC2 互ping c.验证PC1通过远程登陆到路由器上&#…

C#医学实验室/检验信息管理系统(LIS系统)源码

目录 检验系统的总体目标 LIS主要包括以下功能&#xff1a; LIS是集&#xff1a;申请、采样、核收、计费、检验、审核、发布、质控、耗材控制等检验科工作为一体的信息管理系统。LIS系统不仅是自动接收检验数据&#xff0c;打印检验报告&#xff0c;系统保存检验信息的工具&a…

初级软件测试常见问题

1.JMeter &#xff08;1&#xff09;在http请求的时候&#xff0c;消息体数据中的数据需要用{}和“”标记起来&#xff0c;变量要用${}括起来。 &#xff08;2&#xff09;在响应断言的时候&#xff0c;要根据测试模式输出的内容来改变测试字段&#xff0c;假如输出错误可以把…

系统学c#:1、基础准备(软件下载与安装)

一、Vs软件下载与安装 访问Visual Studio官方网站&#xff1a; https://visualstudio.microsoft.com/zh-hans/downloads 下载Visual Studio 运行exe文件&#xff0c;点击“继续” 初始文件安装完成后选择我们需要安装的项&#xff0c;并勾选好必要的单个组件&#xff0c;设…

代码随想录阅读笔记-回溯【全排列】

题目 给定一个 没有重复 数字的序列&#xff0c;返回其所有可能的全排列。 示例 输入: [1,2,3]输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ] 思路 以[1,2,3]为例&#xff0c;抽象成树形结构如下&#xff1a; 回溯三部曲 1、递归函数参数 首先排列是有…

Emacs之实现复制当前已打开文件buffer(一百三十五)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

Day55 动态规划 part15

Day55 动态规划 part15 392.判断子序列 我的思路&#xff1a; 自己还是只能想到双指针法 解答: class Solution {public boolean isSubsequence(String s, String t) {if(s.length() 0) {return true;}if(s.length() > t.length() || t.length() 0) {return false;}ch…

(九)C++自制植物大战僵尸游戏自定义对话框的实现

植物大战僵尸游戏开发教程专栏地址http://t.csdnimg.cn/m0EtD 对话框在游戏的交互中非常重要。在游戏中&#xff0c;对话框不仅可以提醒用户下达任务指令&#xff0c;而且还可以让用户进行操作&#xff0c;自定义游戏中的各种属性。对话框在游戏的交互中非常常见且大量使用。Co…

LigaAI x 极狐GitLab,共探 AI 时代研发提效新范式

近日&#xff0c;LigaAI 和极狐GitLab 宣布合作&#xff0c;双方将一起探索 AI 时代的研发效能新范式&#xff0c;提供 AI 赋能的一站式研发效能解决方案&#xff0c;让 AI 成为中国程序员和企业发展的新质生产力。 软件研发是一个涉及人员多、流程多、系统多的复杂工程&#…

[docker] 核心知识 - 概念和运行

[docker] 核心知识 - 概念和运行 之前 docker 学了个开头就去搞项目去了&#xff0c;不过项目也开展了好久了&#xff0c;前端差不多吃透了&#xff0c;有些新功能需要用 docker 和 k8s……是时候重新学习一下了。 这一部分简单的过一下概念和讲一下怎么运行 docker 镜像和启…

wps使用Latex编辑公式没有Latex formula

wps使用Latex编辑公式没有Latex formula 1. 下载CTEX2. 下载LaTeXEE3. 配置Miktex4. 配置latexee5. 用管理员权限运行latexeqedit.exe6. wps插入latex公式 1. 下载CTEX 下载CTEX网址&#xff0c;我下载的下图这个&#xff0c;下载完了之后运行exe文件安装ctex。 2. 下载LaTe…

深入理解k8s kube-proxy

1、概述 我觉得只要大家知道kube-proxy是用来配置网络规则的而不是转发流量的&#xff0c;真正的流量由iptables/ipvs来转发就可以了。 网络是k8s的一个关键部分。理解k8s中网络组件如何工作可以帮助更好的设计和配置我们的应用。 kube-proxy就是K8s网络的核心组件。它把我们…

janus部署

配置和运行janus 1. 配置nginx 安装nginx&#xff0c;主要用来提供web访问。 生成证书 mkdir -p ~/cert cd ~/cert # CA私钥 openssl genrsa -out key.pem 2048 # 自签名证书 openssl req -new -x509 -key key.pem -out cert.pem -days 1095安装nginx #下载nginx 1.15.8版…

OOCT WPF_D3D项目报错无法加载依赖项

运行示例项目报错缺少dll&#xff0c;发现运用了这个大老李&#xff0c;通过添加PATH路径也无法解决&#xff0c;看到debug文件夹下面没有其他的依赖项。 通过depneds工具可以看到 OCCTProxy_D3D.dll 缺少依赖项&#xff0c;图中的缺项都是OCCT生成的模块dll所以讲这些dll从..…

百度 千帆sdk 试用

主要是Java SDK的使用&#xff1a; <dependency> <groupId>com.baidubce</groupId> <artifactId>qianfan</artifactId> <version>0.0.4</version> </dependency> 参考文档&#xff1a;bce-qianfan-sdk/java at main baidub…

【CVE-2010-2883】进行钓鱼攻击的研究

最近作业中研究APT攻击&#xff0c;了解到2011年前后披露的LURID-APT&#xff0c;其中敌手利用了各种版本的文件查看器的漏洞实现攻击。CVE-2010-2883就是其中被利用的一个adobe reader的漏洞。特此复现&#xff0c;更好的研究和防范APT攻击。 本文仅仅是对相关漏洞利用的学习…

若依前后端部署到一起

引用&#xff1a;https://blog.csdn.net/qq_42341853/article/details/129127553 前端改造&#xff1a; 配置打包前缀 修改router.js 编程hash模式&#xff1a; 前端打包&#xff1a;npm run build:prod 后端修改&#xff1a; 添加thymeleaf包&#xff0c;和配置文件 spri…

spring-cloud微服务gateway

核心部分&#xff1a;routes(路由)&#xff0c; predicates(断言)&#xff0c;filters(过滤器) id&#xff1a;可以理解为是这组配置的一个id值&#xff0c;请保证他的唯一的&#xff0c;可以设置为和服务名一致 uri&#xff1a;可以理解为是通过条件匹配之后需要路由到&…

rhce day1

一 . 在系统中设定延迟任务要求如下 在系统中建立 easylee 用户&#xff0c;设定其密码为 easylee 延迟任务由 root 用户建立 要求在 5 小时后备份系统中的用户信息文件到 /backup 中 确保延迟任务是使用非交互模式建立 确保系统中只有 root 用户和 easylee 用户可以执行延…

线性表概念及顺序表的实现

文章目录 前言一、线性表1.定义2.特点3.一般线性表的抽象数据类型定义 二、线性表的顺序存储&#xff08;顺序表&#xff09;1.基本概念2.数组实现顺序表3.顺序表中基本操作的具体实现4.顺序表总结 总结 前言 T_T此专栏用于记录数据结构及算法的&#xff08;痛苦&#xff09;学…