LeetCode —— Anagrams

链接:http://leetcode.com/onlinejudge#question_49

原题:

Given an array of strings, return all groups of strings that are anagrams.

Note: All inputs will be in lower-case.

思路:什么是anagram?一个字符串,把它的字母任意调换位置后,得到的字符串就叫原来的anagram,也就是原串的一个置换。

要把这些字符串全部找出来,我是自己实现了一个hashtable做的。key是该字符串的字母和,然后取余数。一旦发生冲突,就检查

是不是anagram。 最后是328ms跑过的。

在discussion里面,有另外比较简洁的做法,就是把每个string排序作为key,再用unordered_map,196ms跑过。


代码:

const int NUM = 26;
struct Node {
	bool used;
	string str;
	vector<int> signature;
	Node *next;

	Node(): next(NULL) {}
	Node(const string &s): used(false), str(s), next(NULL) {
		signature.assign(NUM, 0);
		for (int i=0; i<str.size(); i++)
			signature[str[i]-'a']++;
	}
};

class Solution {
public:
    vector<string> anagrams(vector<string> &strs) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function

		vector<string> collection;

		freeSpace();
		Node head;
		hashTable.assign(SIZE, head);

		for (int n=0; n<strs.size(); n++) {
			int key = getKey(strs[n]);
			if (hashTable[key].next == NULL) {
				hashTable[key].next = new Node(strs[n]);
			} else {
				Node *cur = new Node(strs[n]);
				Node *ptr = hashTable[key].next;
				while (ptr) {
					if (ptr->signature == cur->signature) {
						collection.push_back(strs[n]);
						if (ptr->used == false) {
							collection.push_back(ptr->str);
							ptr->used = true;
						}
						delete cur;
						break;
					}
					ptr = ptr->next;
				}

				if (ptr == NULL) {
					cur->next = hashTable[key].next;
					hashTable[key].next = cur;
				}
			}
		}

		return collection;
    }

private:
	void freeSpace() {
		for (int i=0; i<hashTable.size(); i++) {
			Node * ptr = hashTable[i].next;
			while (ptr) {
				Node *pre = ptr->next;
				delete ptr;
				ptr = pre;
			}
		}

		hashTable.clear();
	}

	int getKey(const string &str) {
		int sum = 0;
		for (int i=0; i<str.size(); i++)
			sum += (str[i] - 'a');
		return sum % SIZE;
	}

	const static int SIZE = 101;
	vector<Node> hashTable;
};



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值