C算法-并查集

leetcode684题,冗余链接。第N 遍忘记了malloc和memset一定要用sizeof(xx) * length了,晕死
leetcode200题,岛屿数量。leetcode有个坑是要判断行是否为空,如果为空的情况列的地址也是空,对列进行操作就会报错。所以先判断一把,如果行是0可以直接返回了,如下:
leetcode695题,岛屿的最大面积。之前都是求-1的节点,一个for循环很简单搞定。此题要求最大的团队数量,目前思考出来的思路是:1、结束后对每个成员getleader(),保证性能优化点二的坑补上;2、对所有是-1的成员,赋值为自己;3、快排+for循环计数最大团队。

    size = gridSize;
    count = 0;
    if (size == 0) {
        return 0;
    }

并查集的用途这位大哥讲的很详细,https://blog.csdn.net/qq_41593380/article/details/81146850

一、主要思想就是:
1、查找多少个团队,就是查找有多少个团队大哥。默认团队大哥的标识是-1
2、A和B有关系,那么我去把A的大哥找出来,B的大哥也找出来。参照如下set()函数
3、让大哥之间选出个新大哥,这样他们就是一个团队了。参照如下set()函数
所以我们只需要存自己的大哥是谁的数组。如果自己就是大哥,可以把自己的大哥赋值为一个奇怪的数字识别,例如-1,-1代表自己是大哥,手里有刀,心中有剑,身边有兄弟。
二、性能优化点:
1、找A的大哥,可以用while循环。但是对比较大的用例,这样会超时。
2、把A记下来,我们找到A的大哥以后,可以顺便把A的中间哥都赋值成大哥。直辖,不要搞太多地级市和县。参照如下getsleader();注意,这个方法有个小坑是,最后node的结果不一定清理完了所有的地级市。

684答案

#define maxlen 1002
int *g_node;
int getsleader(int person) {
    int tmp, son = person;
    if (g_node[person] == -1) {
        return person;
    }
    while(g_node[person] != -1) {
        person = g_node[person];
    }
    
    while(g_node[son] != -1) {
        tmp = g_node[son];
        g_node[son] = person;
        son = tmp; 
    }
    return person;
    
    
}

int set(int pair1, int pair2) {
    int x = getsleader(pair1);
    int y = getsleader(pair2);
    if (x != y) {
        g_node[y] = x;
        return 0;
    } else {
        return 1;
    }
}

int* findRedundantConnection(int **edges, int edgesSize, int* edgesColSize, int* returnSize) {
    g_node = (int *)malloc(sizeof(int) * maxlen);
    int* result = (int *)malloc(2 * sizeof(int));
    memset(g_node,-1,sizeof(int) *maxlen );
    int i = 0;
    for (i = 0; i < edgesSize; i++) {
        if(set(edges[i][0], edges[i][1]) == 1) {
            result[0] = edges[i][0];
            result[1] = edges[i][1];
            
        }
    }
    *returnSize = 2;
    free(g_node);
    return result;
}

200答案

#define MAXLEN 60000

int g_a[MAXLEN];

int getspara(int person){
    int son = person;
    int tmp;
    while (g_a[person] != -1) {
        person = g_a[person];
    }
    while (g_a[son] != -1) {
        tmp = g_a[son];
        g_a[son] = person;
        son = tmp;
    }

    return person;
}

void set(int a, int b , int max) {
    int x = getspara(a);
    int y = getspara(b);
    if (x != y) {
        g_a[x] = y;
    }

}


int numIslands(char **grid, int gridSize, int *gridColSize)
{
    int i, j, size, ksize, count, max;
    size = gridSize;
    count = 0;
    if (size == 0) {
        return 0;
    }

    ksize = *gridColSize;
    max  = size * ksize; 

    for (i = 0; i < max; i++) {
        g_a[i] = -2;
    }

    for (i = 0; i < size; i++) {
        for (j = 0; j < ksize; j++) {
            if (grid[i][j] == '0') {
                continue;
            }
            g_a[ksize * i + j] = -1;
            if (i > 0 && grid[i - 1][j] == '1'){
                set(i* ksize + j , (i - 1) * ksize+ j , max);                
            }
            if (j > 0 && grid[i][j - 1] == '1'){
                set(i* ksize + j , (j - 1) + i * ksize, max);    
            }
            
            
        }
    }
    for (i = 0; i < max; i++) {
        printf ("%d",g_a[i]);
        if (g_a[i] == -1) {
            count++;
        }
    }
    return count;
}

695答案

#define MAXLEN 2500


int comp1(const void *a, const void *b) {
	return *(int*)b - *(int*)a;
}

int getleader(int person, int *gridtable) {
	int curr = person;
	int currleader;
	while (gridtable[person] != -1) {
		person = gridtable[person];
	}
	while (gridtable[curr] != -1) {
		currleader = gridtable[curr];
		gridtable[curr] = person;
		curr = currleader;
	}
	return person;
}

void getChildinGroup(int neibournum, int person, int neibour, int *gridtable) {
	if (neibournum == 0) {
		return;
	}
	int a = getleader(person, gridtable);
	int b = getleader(neibour, gridtable);

	if (a != b) {
		gridtable[b] = a;
	}
}

int maxAreaOfIsland(int** grid, int gridSize, int* gridColSize) {

	if (gridSize == 0) {
		return 0;
	}
	int gridtable[MAXLEN];
	int i, j;
	int totallength = gridSize * gridColSize[0];
	for (i = 0; i < totallength; i++) {
		gridtable[i] = -2;
	}
	for (i = 0; i < gridSize; i++) {
		for (j = 0; j < gridColSize[0]; j++) {
			if (grid[i][j] == 1) {
				gridtable[i * gridColSize[0] + j] = -1;
			}
				
		}
	}
	for (i = 0; i < gridSize; i++) {
		for (j = 0; j < gridColSize[0]; j++) {
			if (grid[i][j] == 0) {
				continue;
			}

			if (j != gridColSize[0] -1) {
				getChildinGroup(grid[i][j + 1], i*gridColSize[0] + j, i*gridColSize[0] + j + 1, gridtable);
			}
			if (i != gridSize - 1) {
				getChildinGroup(grid[i + 1][j], i*gridColSize[0] + j, (i + 1)*gridColSize[0] + j, gridtable);
			}
		}
	}

	for (i = 0; i < totallength; i++) {
		if (gridtable[i] != -2)
			getleader(i,gridtable);
	}

	for (i = 0; i < totallength; i++) {
		if(gridtable[i] == -1)
			gridtable[i] = i;
	}
	qsort(gridtable, totallength, sizeof(int), comp1);
	
	if (gridtable[0] == -2) {
		return 0;
	}
	int maxlen = 1, curr = 1;
	for (i = 1; i < totallength; i++) {
		if (gridtable[i] == -2) {
			break;
		}
		if (gridtable[i] == gridtable[i - 1] ) {
			curr++;
			if (curr > maxlen) {
				maxlen = curr;
			}
		}else {
			curr = 1;
			if (curr > maxlen) {
				maxlen = curr;
			}
		}
	}

	return maxlen;


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值