作者:小迅
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
题目
示例
思路
题意 -> 给定一些文件夹,删除子文件夹
题目已经说的很明确了,所以直接使用 双指针 对于所有字符串进行枚举,判断当前字符串的子文件夹在什么位置并进行删除,当然在代码实现上,并需要进行删除,只需要借助一个数组对所有字符串进行一个标记,记录当前字符串的状态(是否被删除)。
但是过不了,因为在双指针枚举的过程中,每一次枚举当前字符串的子字符串时,必须从头到尾进行枚举,时间消耗大
那么仔细观察可以发现,文件夹的子文件夹的字符串长度肯定会大于自身,那么对于所有字符串先按长度进行一个升序排列,再进行双指针枚举的时候就不需要从头开始了,因为后面的字符串长度肯定大于前面的字符串长度,则后面肯定不会是前面的父文件夹!!!
还有一个小细节,对于当前字符串的子文件夹判断处理时,需要判断子文件夹的下一位是否为 '/' ,否则则说明该文件不是当前字符串的子文件夹,比如 "/a/b/c","/a/b/ca"
代码注释超级详细
代码
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
bool charIsVal(char *str1, char *str2)//文件夹比较函数
{
while (*str2 != '\0' && *str1 != '\0' && *str1 == *str2) {
str1++;
str2++;
}
if (*str1 == '\0' && *str2 == '/') {//同时满足这个两个条件才是子文件夹
return true;
}
return false;
}
int cmp(const void *a, const void *b)//字符串长度升序排列函数
{
char *_a = *(char **)a;
char *_b = *(char **)b;
int len1 = strlen(_a);
int len2 = strlen(_b);
return len1 - len2;
}
char ** removeSubfolders(char ** folder, int folderSize, int* returnSize){
char hash[folderSize];
memset(hash, 0, sizeof(hash));//标记数组
char ** ans = (char **)malloc(sizeof(char *) * 4 * 10000);//记录有效字符串
*returnSize = 0;
qsort(folder, folderSize, sizeof(char *), cmp);//排序
for (int i = 0; i < folderSize; ++i) {//双指针枚举
if (hash[i] == 0) {//未被删除的字符串
for (int j = i + 1; j < folderSize ; ++j) {
if (hash[j] != 0) {//已经被别的字符串删除过了
continue;
}
if (charIsVal(folder[i], folder[j]) == true) {
hash[j] = 1;//满足被删除要求,删除
}
}
ans[(*returnSize)++] = folder[i];//记录头文件夹
}
}
return ans;
}
作者:小迅
链接:https://leetcode.cn/problems/remove-sub-folders-from-the-filesystem/solutions/2099727/shuang-zhi-zhen-pai-xu-zhu-shi-chao-ji-x-rii6/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。