/*
* 算法思想:
* 套用经典回溯算法框架,注意需要带返回值的回溯;
* 题目要求的是返回一种染色方式,并未要求全部的染色方式,一旦符合条件直接返回即可,而不是遍历所有的可能。
* 详细见代码中注释。
*
*/
/* check函数用于检查当前index位置染得颜色是否符合要求,,index之前的染色一定符合要求 */
bool check(int *arr, int len, int vst[len+1][4], int index,int **paths, int pathlen){
int i;
#if 0
/* 遍历所有的连接关系,每填充一种颜色,都会便利所有的连接关系,会超时 */
for(i=0; i<pathlen; i++){
if(arr[paths[i][0]-1] == arr[paths[i][1]-1] &&
(arr[paths[i][0]-1] && arr[paths[i][1]-1])){
return false;
}
}
#endif
/* 将链接关系放到一张表中,vst中,该表存放所有的关系,仅仅查看已经当前染色的index位置的关系,
* 是否符合条件。
*/
for(i=0; i<vst[index+1][3]; i++){
if(arr[index] == arr[vst[index+1][i]-1] &&
(arr[index] && arr[vst[index+1][i]-1])){
return false;
}
}
return true;
}
/* 回溯,对index位置进行染色, */
int set(int *arr, int len, int vst[len+1][4],int index, int **paths, int pathlen){
int i;
if(index >= len){
return 1;
}
for(i=4; i>=1; i--){
arr[index] = i;
/* 如果不符合条件,当前填充无效,continue进行下一轮的填充,check通过才能进行下一位置的染色 */
if(!check(arr, len, vst, index, paths, pathlen)){
continue;
}else{
//print(arr, len);
if(index == len-1){
return 1;
}
/* 如果已经填充完毕,直接返回,不用进行下一轮的回溯了 */
if(set(arr, len, vst,index+1, paths, pathlen)){
return 1;
}
}
}
return 0;
}
int* gardenNoAdj(int N, int** paths, int pathsSize, int* pathsColSize, int* returnSize){
int *arr = (int *)malloc(sizeof(int) * (N+2));
int vst[N+1][4];
int i;
/* 对vst[N+1][4]解释如下:
* vst[0]无效,从index=1开始,vst[index][3]表示index位置的关系数,最大为3个关系,即最大与index位置发生相连的数目为3;
* 对于0=<i<=3, vst[index][i]表示与位置index相连的节点的位置vst[index][i],可直接判断
* arr[index] =? arr[vst[index+1][i]-1] 判断是否颜色相同。
*
*/
/* set vst[][] */
memset(vst, 0, sizeof(vst));
for(i=0; i<pathsSize; i++) {
vst[paths[i][0]][vst[paths[i][0]][3]] = paths[i][1];
vst[paths[i][0]][3]++;
vst[paths[i][1]][vst[paths[i][1]][3]] = paths[i][0];
vst[paths[i][1]][3]++;
}
/* 如果没有任何关系,将其全部染色成1 */
if(!pathsSize){
int i;
for(i=0; i<N; i++){
arr[i] = 1;
}
}
*returnSize = N;
memset(arr, 0, sizeof(int) * N);
set(arr, N, vst, 0, paths, pathsSize);
return arr;
}
LeetCode-5056-不邻接植花-C语言
最新推荐文章于 2020-08-23 21:45:49 发布