typedef struct{
int key;
int val;
UT_hash_handle hh;
}HashItem;
HashItem *hashFindItem(HashItem **obj,int key){
HashItem *pEntry = NULL;
HASH_FIND_INT(*obj,&key,pEntry);
return pEntry;
}
bool hashAddItem(HashItem **obj, int key, int val) {
if (hashFindItem(obj, key)) {
return false;
}
HashItem *pEntry = (HashItem *)malloc(sizeof(HashItem));
pEntry->key = key;
pEntry->val = val;
HASH_ADD_INT(*obj, key, pEntry);
return true;
}
bool hashSetItem(HashItem **obj, int key, int val) {
HashItem *pEntry = hashFindItem(obj, key);
if (!pEntry) {
hashAddItem(obj, key, val);
} else {
pEntry->val = val;
}
return true;
}
int hashGetItem(HashItem **obj, int key, int defaultVal) {
HashItem *pEntry = hashFindItem(obj, key);
if (!pEntry) {
return defaultVal;
}
return pEntry->val;
}
void hashFree(HashItem **obj) {
HashItem *curr = NULL, *tmp = NULL;
HASH_ITER(hh, *obj, curr, tmp) {
HASH_DEL(*obj, curr);
free(curr);
}
}
话不多说,直接上code了,大致说明一下如何使用
我们实战中用到最多的就是hashSetItem 和hashGetItem, 写表,读表这两个操作
hashSetltm(&counts,key,val) hashGetltm(&counts,key,val)
好了,已经介绍完毕,那我们就来做到题吧。
思路:
①数组内的数字从1-n,而且还不重复,那说明k只有一个
②中位数:奇数为中间,偶数中间偏左。说明奇数时k为中间值,偶数时k为中间偏左。
③转化思想,大于k的数为1,小于k的数为-1,等于k的数为0
④ nums[idx] = k; k1 < idx < k2 如果k2的前缀和 - k1的前缀和为 1/0,那他就是一个满足条件的子数组
show show code !!
typedef struct{
int key;
int val;
UT_hash_handle hh;
}HashItem;
HashItem *hashFindItem(HashItem **obj,int key){
HashItem *pEntry = NULL;
HASH_FIND_INT(*obj,&key,pEntry);
return pEntry;
}
bool hashAddItem(HashItem **obj, int key, int val) {
if (hashFindItem(obj, key)) {
return false;
}
HashItem *pEntry = (HashItem *)malloc(sizeof(HashItem));
pEntry->key = key;
pEntry->val = val;
HASH_ADD_INT(*obj, key, pEntry);
return true;
}
bool hashSetItem(HashItem **obj, int key, int val) {
HashItem *pEntry = hashFindItem(obj, key);
if (!pEntry) {
hashAddItem(obj, key, val);
} else {
pEntry->val = val;
}
return true;
}
int hashGetItem(HashItem **obj, int key, int defaultVal) {
HashItem *pEntry = hashFindItem(obj, key);
if (!pEntry) {
return defaultVal;
}
return pEntry->val;
}
void hashFree(HashItem **obj) {
HashItem *curr = NULL, *tmp = NULL;
HASH_ITER(hh, *obj, curr, tmp) {
HASH_DEL(*obj, curr);
free(curr);
}
}
int sign(int num)
{
if(num == 0)
{
return 0;
}
return num>0?1:-1;
}
int countSubarrays(int* nums, int numsSize, int k){
HashItem* counts = NULL;
hashSetItem(&counts,0,1);
int sum = 0;
int ans = 0;
int idx;
for(int i = 0;i<numsSize;i++)
{
if(nums[i] == k)
{
idx = i;
break;
}
}
for(int i = 0;i<numsSize;i++)
{
sum += sign(nums[i] - k);
if(i < idx)
{
hashSetItem(&counts,sum,hashGetItem(&counts,sum,0)+1);
}
else
{
int ak0 = hashGetItem(&counts,sum,0);
int ak1 = hashGetItem(&counts,sum-1,0);
ans += ak0 + ak1;
}
}
return ans;
}
over boy!
新增一條,遍歷hash表
int cmp(const void* a, const void* b){
return *(int*)a > *(int*)b;
}
typedef struct{
int key;
int val;
UT_hash_handle hh;
}HashItem;
HashItem *hashFindItem(HashItem **obj,int key){
HashItem *pEntry = NULL;
HASH_FIND_INT(*obj,&key,pEntry);
return pEntry;
}
bool hashAddItem(HashItem **obj, int key, int val) {
if (hashFindItem(obj, key)) {
return false;
}
HashItem *pEntry = (HashItem *)malloc(sizeof(HashItem));
pEntry->key = key;
pEntry->val = val;
HASH_ADD_INT(*obj, key, pEntry);
return true;
}
bool hashSetItem(HashItem **obj, int key, int val) {
HashItem *pEntry = hashFindItem(obj, key);
if (!pEntry) {
hashAddItem(obj, key, val);
} else {
pEntry->val = val;
}
return true;
}
int hashGetItem(HashItem **obj, int key, int defaultVal) {
HashItem *pEntry = hashFindItem(obj, key);
if (!pEntry) {
return defaultVal;
}
return pEntry->val;
}
void hashFree(HashItem **obj) {
HashItem *curr = NULL, *tmp = NULL;
HASH_ITER(hh, *obj, curr, tmp) {
HASH_DEL(*obj, curr);
free(curr);
}
}
int tupleSameProduct(int* nums, int numsSize){
HashItem* counts = NULL;
for(int i = 0;i<numsSize;i++){
for(int j = i+1;j<numsSize;j++){
hashSetItem(&counts,nums[i]*nums[j],hashGetItem(&counts,nums[i]*nums[j],0)+1);
}
}
int ans = 0 ;
for (HashItem *pEntry = counts; pEntry; pEntry = pEntry->hh.next) {
int val = pEntry->val;
ans += val * (val - 1) * 4;
}
return ans;
}