初识搜索
https://leetcode-cn.com/problems/letter-case-permutation/?tdsourcetag=s_pctim_aiomsg
不喜欢在leetcode里那种写函数造轮子的感觉,就自己写了一个C文件完成效果。
给定我们一个字符串,将字符串里面的字母转换成大小写之后获得新的字符串,返回所有新字符串的集合。
很容易可以想到使用dfs和递归,我们对字符串进行遍历,每次遇到一个小写字符,当前位置就先以小写继续递归下去,然后将当前位置的单词换成大写,再以大写的形式递归下去,如果检测到是数字,就继续递归下一位。
由此可以写出代码
#include<stdio.h>
#include<string.h>
char str[13];
int length;
int dfs(int index,char * s){
if((index+1)==length){
printf("%s\n",s);
return 0;
}
if(s[index]>='a'&&s[index]<='z'){
dfs(index+1,s);
s[index]=s[index]-'a'+'A';
dfs(index+1,s);
}else if(s[index]>='A'&&s[index]<='Z'){
dfs(index+1,s);
s[index]=s[index]-'A'+'a';
dfs(index+1,s);
}else{
dfs(index+1,s);
}
}
int main(){
scanf("%s",str);
length=strlen(str);
dfs(0,str);
return 0;
}
第二个题目是岛屿数量
给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。 示例 1: 输入: 11110 11010 11000 00000 输出: 1 示例 2: 输入: 11000 11000 00100 00011 输出: 3
这里我们可以使用遍历岛屿同时使用深度优先搜索来进行查询岛屿的数量。
岛屿是连成一片的’1’,在《啊哈!算法》的搜索章节里面也有类似的应用,也就是“再见炸弹人”。
在岛屿数量的问题中,我们先设置s[4][5]来储存岛屿,用a[4][5]来储存岛屿目前被感染(即被访问了)没有。
如果被感染了,我们就将这个位置的a[i][j]置为1。
遍历每一个岛屿中的每一个元素,将其中是’1’的放入感染函数,感染其周围能够感染的陆地,将他们都置为1,下一次不能重复感染。
感染函数里,检测从当前位置能够感染的陆地,用队列储存陆地,当无法继续扩展的时候退出,回到主函数继续进行遍历。
#include<stdio.h>
#include<stdio.h>
char s[4][5];
int a[4][5]={0};
int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
struct node{
int x;
int y;
};
struct node que[21];
void check(int i,int j){
int start_x=i,start_y=j,head=1,tail=1;
int tx,ty;
que[tail].x=start_x;
que[tail].y=start_y;
tail++;
while(head<tail){
for(int i=0;i<4;i++){
tx=que[head].x+next[i][0];
ty=que[head].y+next[i][1];
if(tx<0||tx>4||ty<0||ty>4){
continue;
}
if(a[tx][ty]==0&&s[tx][ty]=='1'){
a[tx][ty]=1;
que[tail].x=tx;
que[tail].y=ty;
tail++;
}
}
head++;
}
}
int main(){
int sum=0;
for(int i=0;i<4;i++){
scanf("%s",s[i]);
}
for(int i=0;i<4;i++){
for(int j=0;j<5;j++){
if(s[i][j]=='1'&&a[i][j]==0){
check(i,j);
sum++;
}
}
}
printf("%d\n",sum);
return 0;
}