这两道题都比较适合用广度优先算法,
广度优先算法的思路是先把第一步的所有节点保存在队列中,然后依次取出队列中的节点,再将第二步的节点进行保存,直到达到条件或全部搜索完毕停止。
题目
给 n 个进程,每个进程都有一个独一无二的 PID (进程编号)和它的 PPID (父进程编号)。
每一个进程只有一个父进程,但是每个进程可能会有一个或者多个孩子进程。它们形成的关系就像一个树状结构。只有一个进程的 PPID 是 0 ,意味着这个进程没有父进程。所有的 PID 都会是唯一的正整数。
我们用两个序列来表示这些进程,第一个序列包含所有进程的 PID ,第二个序列包含所有进程对应的 PPID。
现在给定这两个序列和一个 PID 表示你要杀死的进程,函数返回一个 PID 序列,表示因为杀这个进程而导致的所有被杀掉的进程的编号。
当一个进程被杀掉的时候,它所有的孩子进程和后代进程都要被杀掉。
你可以以任意顺序排列返回的 PID 序列。
示例 1:
输入:
pid = [1, 3, 10, 5]
ppid = [3, 0, 5, 3]
kill = 5
输出: [5,10]
解释:
3
/
1 5
/
10
杀掉进程 5 ,同时它的后代进程 10 也被杀掉。
示例 2:
输入:
pid = [1, 3, 10, 5, 6 ,7]
ppid = [5, 0, 5, 3, 10, 1]
kill = 5
输出: [5,10]
注意:
被杀掉的进程编号一定在 PID 序列中。
n >= 1.
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/kill-process
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
示例2步骤:
1.可以用广度优先遍历,先将父节点5放入队列1,输出5。
2.取出5,搜索所有父节点为5的节点,并将子节点1,10放入队列2,输出1,10;
3.之前的队列1为空,开始取队列2的值
4.取出1,搜索所有父节点为1的节点,并将子节点7放入队列2,输出7;
5.取出10,搜索所有父节点为10的节点,并将子节点6放入队列2,输出6;
6.之前的队列2为空,开始取队列3的值
7.取出7,搜索所有父节点为7的节点,没有找到,不向队列加入元素;
8.取出6,搜索所有父节点为6的节点,没有找到,不向队列加入元素;
9.队列为空,停止遍历
此外,搜索时为了避免超时,用了二分法搜索。
代码:
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
typedef struct {
int sonPid;
int fatherPid;
} Node;
bool CalMinAndMaxPos(Node* rec, int len, int* min, int* max, int target)
{
int i, j, mid, val;
bool ret = false;
i = 0;
j = len - 1;
while (i <= j) {
mid = (i + j) / 2;
val = rec[mid].fatherPid;
if (val == target) {
*min = mid;
j = mid - 1;
ret = true;
} else if (val > target) {
j = mid - 1;
} else {
i = mid + 1;
}
}
i = 0;
j = len - 1;
while (i <= j) {
mid = (i + j) / 2;
val = rec[mid].fatherPid;
if (val == target) {
*max = mid;
i = mid + 1;
} else if (val > target) {
j = mid - 1;
} else {
i = mid + 1;
}
}
return ret;
}
void Bfs(Node* rec, int pidSize, int* killList, int* returnSize, int kill)
{
int* queue;
int* newQueue;
int* temp;
int i, j, max, min;
queue = (int*)malloc(sizeof(int) * pidSize);
newQueue = (int*)malloc(sizeof(int) * pidSize);
int queLen, newQueLen;
killList[*returnSize] = kill;
(*returnSize)++;
queue[0] = kill;
queLen = 1;
while (queLen) {
newQueLen = 0;
for (i = 0; i < queLen; i++) {
if (CalMinAndMaxPos(rec, pidSize, &min, &max, queue[i]) == false) {
continue;
}
for (j = min; j <= max; j++) {
killList[*returnSize] = rec[j].sonPid;
(*returnSize)++;
newQueue[newQueLen++] = rec[j].sonPid;
}
}
queLen = newQueLen;
temp = queue;
queue = newQueue;
newQueue = temp;
}
}
int Cmp(const void *a1, const void *a2)
{
return ((Node*)a1)->fatherPid - ((Node*)a2)->fatherPid;
}
int* killProcess(int* pid, int pidSize, int* ppid, int ppidSize, int kill, int* returnSize){
/*广度优先搜索*/
int* killList;
Node* rec;
int i;
killList = (int*)malloc(sizeof(int) * pidSize);
(*returnSize) = 0;
if (pidSize < 1) {
return killList;
}
rec = (Node*)malloc(sizeof(Node) * pidSize);
for (i = 0; i < pidSize; i++) {
rec[i].sonPid = pid[i];
rec[i].fatherPid = ppid[i];
}
qsort(rec, pidSize, sizeof(Node), Cmp);
Bfs(rec, pidSize, killList, returnSize, kill);
return killList;
}