LeetCode · 일별 질문 · 2488. 통계적 중앙값 K 하위 배열 · 해시 + 접두사 합계

저자: 샤오쉰

링크: https://leetcode.cn/problems/count-subarrays-with-median-k/solutions/2172155/ha-xi-qian-zhui-he-zhu-shi-chao-ji-xiang-hgpu/

출처: 리트코드

저작권은 작가에게 있습니다. 상업용 전재의 경우 저자에게 승인을 요청하고 비상업적 전재의 경우 출처를 표시하십시오.

주제

생각의 기차

제목 -> 배열이 주어지면 중앙값이 k인 하위 배열의 수를 반환합니다.

  • 중앙값은 k의 하위 배열과 같고 조건을 만족하는 하위 배열은 k의 위치 주변에서 계산되어야 합니다. 토픽은 k보다 큰 수는 1이거나 k보다 작은 수와 같다는 것을 알고 있으므로 계산의 편의를 위해 기여도는 1보다 크고 기여도 -1보다 작고 기여도 자체는 0입니다.

  • 이렇게 접두사 sum을 세고 k bit를 end bit로 사용하고 왼쪽 start bit의 count를 고려하여 합은 현재값과 현재값에서 1을 뺀 값이 되고, 즉, k 이후 간격의 합은 0,1입니다. .

코드


typedef struct {//哈希结构
    int key;
    int val;
    UT_hash_handle hh;
} HashItem; 

HashItem *hashFindItem(HashItem **obj, int key) {//查询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);             
    }
}

static inline int sign(int num) {//取大小贡献
    if (num == 0) {
        return 0;
    }
    return num > 0 ? 1 : -1;
}

int countSubarrays(int* nums, int numsSize, int k) {
    int kIndex = -1;
    for (int i = 0; i < numsSize; i++) {//找k位置
        if (nums[i] == k) {
            kIndex = i;
            break;
        }
    }
    int ans = 0;
    HashItem *counts = NULL;
    hashAddItem(&counts, 0, 1);//入哈希表
    int sum = 0;
    for (int i = 0; i < numsSize; i++) {//遍历
        sum += sign(nums[i] - k);
        if (i < kIndex) {//小于k的位置
            hashSetItem(&counts, sum, hashGetItem(&counts, sum, 0) + 1);
        } else {//大于k的位置
            int prev0 = hashGetItem(&counts, sum, 0);
            int prev1 = hashGetItem(&counts, sum - 1, 0);//取贡献值
            ans += prev0 + prev1;
        }
    }
    hashFree(&counts);
    return ans;
}



作者:小迅
链接:https://leetcode.cn/problems/count-subarrays-with-median-k/solutions/2172155/ha-xi-qian-zhui-he-zhu-shi-chao-ji-xiang-hgpu/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

추천

출처blog.csdn.net/m0_64560763/article/details/129583342