leetcode-字符串-简单-C-第二部分

序号606

题目:你需要采用前序遍历的方式,将一个二叉树转换成一个由括号和整数组成的字符串。
空节点则用一对空括号 “()” 表示。而且你需要省略所有不影响字符串与原始二叉树之间的一对一映射关系的空括号对。

解析

  1. 递归
    strcat 不能连接 NULL,所以另建函数完成
    连接当前值在本层完成
    连接括号在上层完成
#define MAX 24000
void Tostr(struct TreeNode *t, char *ans)
{
    
    
	char temp[10];
	if (t)
	{
    
    
		sprintf(temp, "%d", t->val);  //本层完成数据连接
		strcat(ans, temp);
		if (t->left || t->right)
		{
    
    
			strcat(ans, "(");
			Tostr(t->left, ans);
			strcat(ans, ")");
		}
		if (t->right)
		{
    
    
			strcat(ans, "(");
			Tostr(t->right, ans);
			strcat(ans, ")");
		}
	}
}

char * tree2str(struct TreeNode* t){
    
    
	char *ans = (char *)calloc(MAX, sizeof(char));
	Tostr(t, ans);
	return ans;
}

注:MAX 是测试出来的
源自于题解

序号657

题目:在二维平面上,有一个机器人从原点 (0, 0) 开始。给出它的移动顺序,判断这个机器人在完成移动后是否在 (0, 0) 处结束。
移动顺序由字符串表示。字符 move[i] 表示其第 i 次移动。机器人的有效动作有 R(右),L(左),U(上)和 D(下)。如果机器人在完成所有动作后返回原点,则返回 true。否则,返回 false。
注意:机器人“面朝”的方向无关紧要。 “R” 将始终使机器人向右移动一次,“L” 将始终向左移动等。此外,假设每次移动机器人的移动幅度相同。

解析

  1. 模拟
    设置 x, y 两个变量表示方向
bool judgeCircle(char * moves){
    
    
	int x = 0;
	int y = 0;

	for (int i = 0; moves[i] != '\0'; ++i)
	{
    
    
		switch(moves[i])
		{
    
    
			case 'U': y++; break;
			case 'D': y--; break;
			case 'L': x--; break;
			case 'R': x++; break;
		}
	}
	return x == 0 && y == 0;
}

序号680

题目:给定一个非空字符串 s,最多删除一个字符。判断是否能成为回文字符串。

解析

  1. 模拟
    先找到第一次不相等的两个点,进行两次判断。
    删去左边那个点
    删去右边两个点
bool IsPalindrome(char* s, int start, int end)
{
    
    
	while (start < end)
	{
    
    
		if (s[start] != s[end])
			return false;
		++start;
		--end;
	}
	return true;
}

bool validPalindrome(char* s) {
    
    
	int len = strlen(s);
	int i = 0;
	int j = len - 1;
	while (i < j)
	{
    
    
		if (s[i] == s[j])
		{
    
    
			++i;
			--j;
		}
		else
			break;
	}
	return IsPalindrome(s, i + 1, j) || IsPalindrome(s, i, j - 1);  //两次判断
}

序号686

题目:给定两个字符串 A 和 B, 寻找重复叠加字符串A的最小次数,使得字符串B成为叠加后的字符串A的子串,如果不存在则返回 -1。
举个例子,A = “abcd”,B = “cdabcdab”。
答案为 3, 因为 A 重复叠加三遍后为 “abcdabcdabcd”,此时 B 是其子串;A 重复叠加两遍后为"abcdabcd",B 并不是其子串。

解析

  1. 模拟
    判定 B 是 A 的子串,A 的长度必须不小于 B
    长度满足后,一定在 2 次添加内找到,找不到返回 -1
int repeatedStringMatch(char* A, char* B) {
    
    
	int lenA = strlen(A);
	int lenB = strlen(B);
	int cnt = 0;
	char* p;
	char temp[30010] = "";
	while (strlen(temp) < lenB)
	{
    
    
		strcat(temp, A);
		cnt++;
	}
	if (p = strstr(temp, B))
		return cnt;
	strcat(temp, A);
	cnt++;
	if (p = strstr(temp, B))
		return cnt;
	return -1;
}

序号696

题目:给定一个字符串 s,计算具有相同数量0和1的非空(连续)子字符串的数量,并且这些子字符串中的所有0和所有1都是组合在一起的。
重复出现的子串要计算它们出现的次数。

解析

  1. 模拟分组
    比较连续的 0 和 1 个数,可以把他们各自分组,再按整体内个数计数
int countBinarySubstrings(char* s) {
    
    
	int cnt = 0;
	int len = strlen(s);
	int pre = 0;
	int cur = 1;
	for (int i = 1; i < len; ++i)
	{
    
    
		if (s[i - 1] != s[i])
		{
    
    
			cnt += pre < cur ? pre : cur;
			pre = cur;
			cur = 1;
		}
		else
			cur++;
	}
    cnt += pre < cur ? pre : cur;  //到末尾时还需再加一次
	return cnt;
}

序号709

题目:实现函数 ToLowerCase(),该函数接收一个字符串参数 str,并将该字符串中的大写字母转换成小写字母,之后返回新的字符串。

解析

  1. 模拟
    找到大写字母,转成小写字母
char * toLowerCase(char * str){
    
    
	for (int i = 0; i < strlen(str); ++i)
	{
    
    
		if (isupper(str[i]))
			str[i] = tolower(str[i]);
	}
	return str;
}

序号788

题目:我们称一个数 X 为好数, 如果它的每位数字逐个地被旋转 180 度后,我们仍可以得到一个有效的,且和 X 不同的数。要求每位数字都要被旋转。
如果一个数的每位数字被旋转以后仍然还是一个数字, 则这个数是有效的。0, 1, 和 8 被旋转后仍然是它们自己;2 和 5 可以互相旋转成对方(在这种情况下,它们以不同的方向旋转,换句话说,2 和 5 互为镜像);6 和 9 同理,除了这些以外其他的数字旋转以后都不再是有效的数字。
现在我们有一个正整数 N, 计算从 1 到 N 中有多少个数 X 是好数?

解析
1.模拟
出现 3、4、7 则不是
必须出现至少一次 2、5、6、9 的其中一个

int rotatedDigits(int N){
    
    
	char str[5];
	int cnt = 0;
	for (int i = 1; i <= N; ++i)
	{
    
    
		sprintf(str, "%d", i);
		int i;
		int flag = 0;
		for (i = 0; i < strlen(str); ++i)
		{
    
    
			if ((str[i] == '3')
				|| (str[i] == '4')
				|| (str[i] == '7'))
			break;
			if ((str[i] == '2')
				|| (str[i] == '5')
				|| (str[i] == '6')
				|| (str[i] == '9'))
				flag = 1;
		}	
		if (i == strlen(str) && flag == 1)
			cnt++;
	}
	return cnt;
}

序号804

题目:国际摩尔斯密码定义一种标准编码方式,将每个字母对应于一个由一系列点和短线组成的字符串, 比如: “a” 对应 “.-”, “b” 对应 “-…”, “c” 对应 “-.-.”, 等等。
为了方便,所有26个英文字母对应摩尔斯密码表如下:
[".-","-…","-.-.","-…",".","…-.","–.","…","…",".—","-.-",".-…","–","-.","—",".–.","–.-",".-.","…","-","…-","…-",".–","-…-","-.–","–…"]
给定一个单词列表,每个单词可以写成每个字母对应摩尔斯密码的组合。例如,“cab” 可以写成 “-.-…–…”,(即 “-.-.” + “-…” + ".-"字符串的结合)。我们将这样一个连接过程称作单词翻译。
返回我们可以获得所有词不同单词翻译的数量。

解析

  1. 暴力检查重复
    先转换当前字符串,再检查重复,不重则加入答案
int uniqueMorseRepresentations(char ** words, int wordsSize){
    
    
	char Morse[26][5] = {
    
    ".-","-...","-.-.","-..",".","..-.","--.",
	"....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",
	".-.","...","-","..-","...-",".--","-..-","-.--","--.."};
	char ans[101][50];
	int cnt = 0;
	for (int i = 0; i < wordsSize; ++i)
	{
    
    
		char temp[50];
        temp[0] = '\0';
		for (int j = 0; j < strlen(words[i]); ++j)
		{
    
    
			char ch = words[i][j];
			strcat(temp, Morse[ch - 'a']);
		}

		int k = 0;
		for (; k < cnt; ++k)
		{
    
    
			if (!strcmp(ans[k], temp))
				break;
		}
		if (k == cnt)
		{
    
    
			strcpy(ans[cnt], temp);
			cnt++;
		}
	}
	return cnt;
}

猜你喜欢

转载自blog.csdn.net/qq_40860934/article/details/105299052
今日推荐