451.根据字符出现频率排序
给定一个字符串 s ,根据字符出现的 频率 对其进行 降序排序 。一个字符出现的 频率 是它出现在字符串中的次数。
返回 已排序的字符串 。如果有多个答案,返回其中任何一个。
示例 1:
输入: s = "tree"
输出: "eert"
解释: 'e'出现两次,'r'和't'都只出现一次。
因此'e'必须出现在'r'和't'之前。此外,"eetr"也是一个有效的答案。
示例 2:输入: s = "cccaaa"
输出: "cccaaa"
解释: 'c'和'a'都出现三次。此外,"aaaccc"也是有效的答案。
注意"cacaca"是不正确的,因为相同的字母必须放在一起。
示例 3:输入: s = "Aabb"
输出: "bbAa"
解释: 此外,"bbaA"也是一个有效的答案,但"Aabb"是不正确的。
注意'A'和'a'被认为是两种不同的字符。
提示:
1 <= s.length <= 5 * 105
s 由大小写英文字母和数字组成来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sort-characters-by-frequency
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
桶排序。
#define HASH_FIND_CHAR(head, findint, out) HASH_FIND(hh, head, findint, sizeof(char), out)
#define HASH_ADD_CHAR(head, intfield, add) HASH_ADD(hh, head, intfield, sizeof(char), add)
struct HashTable {
char key;
int val;
UT_hash_handle hh;
};
char* frequencySort(char* s) {
struct HashTable* hashTable = NULL;
int maxFreq = 0;
int length = strlen(s);
for (int i = 0; i < length; i++) {
struct HashTable* tmp;
HASH_FIND_CHAR(hashTable, &s[i], tmp);
if (tmp == NULL) {
tmp = malloc(sizeof(struct HashTable));
tmp->key = s[i], tmp->val = 1;
HASH_ADD_CHAR(hashTable, key, tmp);
maxFreq = fmax(maxFreq, 1);
} else {
maxFreq = fmax(maxFreq, ++tmp->val);
}
}
char* buckets[maxFreq + 1];
int bucketsSize[maxFreq + 1];
memset(bucketsSize, 0, sizeof(bucketsSize));
int retSize = 0;
struct HashTable *tmp, *iter;
HASH_ITER(hh, hashTable, iter, tmp) {
bucketsSize[iter->val]++;
retSize += iter->val;
}
for (int i = 1; i <= maxFreq; i++) {
buckets[i] = malloc(sizeof(char) * bucketsSize[i]);
}
memset(bucketsSize, 0, sizeof(bucketsSize));
HASH_ITER(hh, hashTable, iter, tmp) {
buckets[iter->val][bucketsSize[iter->val]++] = iter->key;
}
char* ret = malloc(sizeof(char) * (retSize + 1));
retSize = 0;
for (int i = maxFreq; i > 0; i--) {
char* bucket = buckets[i];
for (int j = 0; j < bucketsSize[i]; j++) {
for (int k = 0; k < i; k++) {
ret[retSize++] = bucket[j];
}
}
}
ret[retSize] = '\0';
return ret;
}
给定一个数组 points ,其中 points[i] = [xi, yi] 表示 X-Y 平面上的一个点,并且是一个整数 k ,返回离原点 (0,0) 最近的 k 个点。
这里,平面上两点之间的距离是 欧几里德距离( √(x1 - x2)2 + (y1 - y2)2 )。
你可以按 任何顺序 返回答案。除了点坐标的顺序之外,答案 确保 是 唯一 的。
示例 1:
输入:points = [[1,3],[-2,2]], k = 1
输出:[[-2,2]]
解释:
(1, 3) 和原点之间的距离为 sqrt(10),
(-2, 2) 和原点之间的距离为 sqrt(8),
由于 sqrt(8) < sqrt(10),(-2, 2) 离原点更近。
我们只需要距离原点最近的 K = 1 个点,所以答案就是 [[-2,2]]。
示例 2:输入:points = [[3,3],[5,-1],[-2,4]], k = 2
输出:[[3,3],[-2,4]]
(答案 [[-2,4],[3,3]] 也会被接受。)
提示:
1 <= k <= points.length <= 104
-104 < xi, yi < 104来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/k-closest-points-to-origin
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
堆排,没用UT_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().
*/
#define SIZE 20000
void minHeapify(int* a,int** b,int i,int heapSize){
int l=i*2+1,r=i*2+2,smallest=i;
if(l<heapSize&&a[l]<a[smallest]){
smallest=l;
}
if(r<heapSize&&a[r]<a[smallest]){
smallest=r;
}
if(smallest!=i){
int t=a[i];
a[i]=a[smallest],a[smallest]=t;
int* tmp=b[i];
b[i]=b[smallest],b[smallest]=tmp;
minHeapify(a,b,smallest,heapSize);
}
}
void buildMinHeap(int* a,int** b,int heapSize){
for(int i=heapSize/2;i>=0;i--){
minHeapify(a,b,i,heapSize);
}
}
int** kClosest(int** points, int pointsSize, int* pointsColSize, int k, int* returnSize, int** returnColumnSizes){
*returnSize=0;
if(pointsSize==0) return NULL;
int** ret=malloc(sizeof(int*)*SIZE);
*returnColumnSizes=malloc(sizeof(int)*SIZE);
int distance[pointsSize];
for(int i=0;i<pointsSize;i++){
distance[i]=points[i][0]*points[i][0]+points[i][1]*points[i][1];
}
int heapSize=pointsSize;
int** b=points;
buildMinHeap(distance,b,heapSize);
for(int i=pointsSize-1;i>=pointsSize-k;i--){
(*returnColumnSizes)[*returnSize]=2;
ret[*returnSize]=malloc(sizeof(int)*2);
ret[*returnSize][0]=b[0][0];
ret[*returnSize][1]=b[0][1];
(*returnSize)++;
int t=distance[0];
distance[0]=distance[i],distance[i]=t;
int* tmp=b[0];
b[0]=b[i],b[i]=tmp;
heapSize--;
buildMinHeap(distance,b,heapSize);
}
return ret;
}
好了基础篇完成,暂时性结束,考研去了~