leetcode49. 字母异位词分组

Posted BHY_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode49. 字母异位词分组相关的知识,希望对你有一定的参考价值。

题目链接https://leetcode-cn.com/problems/group-anagrams/

题目:给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。

示例:

输入: ["eat", "tea", "tan", "ate", "nat", "bat"],
输出:
[
  ["ate","eat","tea"],
  ["nat","tan"],
  ["bat"]
]

说明

所有输入均为小写字母。
不考虑答案输出的顺序。

分析:与前两道题同样,本题采用C语言的uthash库,这一道题与36. 有效的数独136. 只出现一次的数字的 区别在于key是字符串,因此我们对uthash的接口重新进行了封装,本次的封装的key可以是结构体,同样可以在前两道题使用,这样的封装更具有拓展性。本地还用到了字符串排序与拷贝接口。

重新封装的接口如下,我们将key和val都作为结构体类型便于扩展,print接口需要根据需求自行修改:

typedef struct 
	int a;
	char b[20];
 uthash_key_s;

typedef struct 
	int c;
	char d;
 uthash_val_s;

typedef struct 
	uthash_key_s key;
	uthash_val_s val;
	UT_hash_handle hh;
 uthash_map_s;

uthash_map_s* uthash_create(void)

	uthash_map_s *s = (uthash_map_s *)malloc(sizeof(uthash_map_s));
	s = NULL;
	return s;


void uthash_add(uthash_map_s **hash, uthash_key_s key, uthash_val_s val)

	uthash_map_s *s;

	HASH_FIND(hh, *hash, &key, sizeof(uthash_key_s), s);
	if (s == NULL) 
		s = (uthash_map_s *)malloc(sizeof(*s));
		s->key = key;
		HASH_ADD(hh, *hash, key, sizeof(uthash_key_s), s);
	
	s->val = val;


uthash_map_s* uthash_find(uthash_map_s **hash, uthash_key_s key)

	uthash_map_s *s;

	HASH_FIND(hh, *hash, &key, sizeof(uthash_key_s), s);
	return s;


void uthash_delete(uthash_map_s **hash, uthash_key_s key)

	uthash_map_s *s;

	HASH_FIND(hh, *hash, &key, sizeof(uthash_key_s), s);
	if (s != NULL) 
		HASH_DEL(*hash, s);
		free(s);
	


void uthash_delete_all(uthash_map_s **hash)

	uthash_map_s *s, *tmp;

	HASH_ITER(hh, *hash, s, tmp) 
		HASH_DEL(*hash, s);
		free(s);
	


void uthash_print(uthash_map_s **hash)

	uthash_map_s *s;

	for (s = *hash; s != NULL; s = (uthash_map_s *)(s->hh.next)) 
		printf("key %d: val %d\\n", s->key.a, s->val.c); // 自行根据数据结构修改
	


unsigned int uthash_get_count(uthash_map_s **hash)

	return HASH_COUNT(*hash);


void uthash_test(void)

	// create
	uthash_map_s *hash = uthash_create();

	// add
	uthash_key_s key;
	key.a = 1;
	strcpy(key.b, "aaa");
	uthash_val_s val;
	val.c = 10;
	val.d = 'h';
	uthash_add(&hash, key, val);
	uthash_print(&hash);
	printf("\\n");
	key.a = 2;
	strcpy(key.b, "bbb");
	val.c = 11;
	val.d = 'j';
	uthash_add(&hash, key, val);
	uthash_print(&hash);
	printf("\\n");

	// find
	uthash_key_s key2;
	key2.a = 1;
	strcpy(key2.b, "aaa");
	if (uthash_find(&hash, key2) != NULL) 
		printf("find key\\n");
	

	// count
	printf("hash map num:%d\\n", uthash_get_count(&hash));

	// delete
	uthash_delete(&hash, key2);
	uthash_print(&hash);
	printf("\\n");

	// delete all
	uthash_delete_all(&hash);
	printf("hash map num:%d\\n", uthash_get_count(&hash));

对以上的通用结构再次改造,以适应本题:

#define CHAR_NUM 1000

typedef struct 
	char name[CHAR_NUM];
 uthash_key_s;

typedef struct 
	int index;
 uthash_val_s;

typedef struct 
	uthash_key_s key;
	uthash_val_s val;
	UT_hash_handle hh;
 uthash_map_s;

uthash_map_s* uthash_create(void)

	uthash_map_s *s = (uthash_map_s *)malloc(sizeof(uthash_map_s));
	s = NULL;
	return s;


void uthash_add(uthash_map_s **hash, uthash_key_s key, uthash_val_s val)

	uthash_map_s *s;
 
	HASH_FIND(hh, *hash, &key, sizeof(uthash_key_s), s);
	if (s == NULL) 
		s = (uthash_map_s *)malloc(sizeof(*s));
		s->key = key;
		HASH_ADD(hh, *hash, key, sizeof(uthash_key_s), s);
	
	s->val = val;


uthash_map_s* uthash_find(uthash_map_s **hash, uthash_key_s key)

	uthash_map_s *s;

	HASH_FIND(hh, *hash, &key, sizeof(uthash_key_s), s);
	return s;


void uthash_delete(uthash_map_s **hash, uthash_key_s key)

	uthash_map_s *s;

	HASH_FIND(hh, *hash, &key, sizeof(uthash_key_s), s);
	if (s != NULL) 
		HASH_DEL(*hash, s);
		free(s);
	


void uthash_delete_all(uthash_map_s **hash)

	uthash_map_s *s, *tmp;

	HASH_ITER(hh, *hash, s, tmp) 
		HASH_DEL(*hash, s);
		free(s);
	


void uthash_print(uthash_map_s **hash)

	uthash_map_s *s;

	for (s = *hash; s != NULL; s = (uthash_map_s *)(s->hh.next)) 
		printf("key %s: val %d\\n", s->key.name, s->val.index); // 自行根据数据结构修改
	


unsigned int uthash_get_count(uthash_map_s **hash)

	return HASH_COUNT(*hash);


/**
 * 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().
 */
int cmp(const char* a, const char* b)

    return *a - *b;


char *** groupAnagrams(char ** strs, int strsSize, int* returnSize, int** returnColumnSizes)
    if (strsSize <= 0 || strs == NULL) 

        return NULL;    
    
   
    char ***res = (char***)malloc(sizeof(char**) * strsSize);
    for (int i = 0; i < strsSize; i++) 
        res[i] = (char**)malloc(sizeof(char*) * strsSize);
    

    *returnSize = 0;
    *returnColumnSizes = (int*)malloc(sizeof(int*) * strsSize);
    memset(*returnColumnSizes, 0, sizeof(int*) * strsSize);
  
    uthash_map_s *hash = uthash_create();
    uthash_key_s key;
    uthash_val_s val;
    uthash_map_s *hash_tmp;
    val.index = 0;
    int row, col;
    for (int i = 0; i < strsSize; i++) 
        memset(key.name, 0, CHAR_NUM);
        strcpy(key.name, strs[i]);
        qsort(key.name, strlen(key.name), sizeof(char), cmp);
        
        hash_tmp = uthash_find(&hash, key);
        if(hash_tmp == NULL) 
            row = val.index;
            col = 0;
            uthash_add(&hash, key, val);
            val.index++;
         else 
            row = hash_tmp->val.index;
            col = *(*returnColumnSizes + row);
        
        res[row][col] = strs[i];
        *(*returnColumnSizes + row) += 1;
    
    
    *returnSize = val.index;
    //uthash_print(&hash);
    uthash_delete_all(&hash);
    
    return res;

执行用时 :152 ms, 在所有 C 提交中击败了42.73%的用户

内存消耗 :269.1 MB, 在所有 C 提交中击败了13.79%的用户

以上是关于leetcode49. 字母异位词分组的主要内容,如果未能解决你的问题,请参考以下文章

Leetcode题库——49.字母异位词分组

LeetCode 49. 字母异位词分组(Group Anagrams)

257.LeetCode | 49. 字母异位词分组

LeetCode 49. 字母异位词分组

[leetcode] 49. 字母异位词分组

leetcode题解之49. 字母异位词分组