IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> [题解]《算法零基础100讲》(第24讲) 字符串算法(四) - 字符计数法 -> 正文阅读

[数据结构与算法][题解]《算法零基础100讲》(第24讲) 字符串算法(四) - 字符计数法

知识讲解

??字符计数法的方法和原理都很简单,原理就是对ASCLL码的引用。
使用方法:
例如我们要统计一个字符串里,小写字母出现的个数

int count(char *s){
	int Hash[26] = { 0 };
	int n = strlen(s);
	for(int i = 0; i < n; i++){
		Hash[s[i] - 'a']++;
	}
}

通过下标来(0~25)表示26个小写字母(a ~ z)。

课后习题

1. 判定字符是否唯一

题目链接:
面试题 01.01. 判定字符是否唯一
这道题我们只需用数组统计每个字母的出现次数,找出只出现过一次的字母即可。

代码如下:

bool isUnique(char* astr){
    int Hash[26] = { 0 };
    int n = strlen(astr);
    for(int i = 0; i < n; i++){
        if(astr[i] >= 'a'){
            Hash[astr[i]- 'a']++;
        }
        else{
            Hash[astr[i]- 'A']++;
        }
        
    }
    for(int i = 0; i < 26; i++){
        if(Hash[i] > 1){
            return false;
        }
    }
    return true;
}

在这里插入图片描述

这种写法可以过力扣上的全部例子,但是有一种特殊情况不行
在这里插入图片描述
所以正确的写法应该如下:

bool isUnique(char* astr){
    int Hash[256] = { 0 };
    int n = strlen(astr);
    for(int i = 0; i < n; i++){
        Hash[astr[i]]++;
    }
    for(int i = 0; i < 256; i++){
        if(Hash[i] > 1){
            return false;
        }
    }
    return true;
}

在这里插入图片描述

2. 第一个只出现一次的字符

题目链接:
剑指 Offer 50. 第一个只出现一次的字符
思路分析:
??由于我们字符串中只有小写字母,所以我们只需考虑小写的情况即可。

代码如下:

char firstUniqChar(char* s){
    int Hash[26] = { 0 };
    int n = strlen(s);

    for(int i = 0; i < n; i++){
        Hash[s[i] - 'a']++;
    }
    for(int i = 0; i < n; i++){
        if(Hash[s[i] - 'a'] == 1){
            return s[i];
        }
    }
    return ' ';
}

在这里插入图片描述

3. 赎金信

题目链接:
383. 赎金信
思路分析:
??这道题其实就是让我们判断是否能用magazine中的字符来表示ransomNota中的字符,所以我们只需要统计两个字符串中的字符类型与个数,然后进行比较,如果ransomNota中有的magazine中都有,则返回true;
代码如下:

bool canConstruct(char * ransomNote, char * magazine){
    int n1 = strlen(ransomNote);
	int n2 = strlen(magazine);
	int arr1[26] = { 0 };
	int arr2[26] = { 0 };
	for (int i = 0; i < n1; i++){
		arr1[ransomNote[i] - 'a']++;
	}
	for (int i = 0; i < n2; i++){
		arr2[magazine[i] - 'a']++;
	}
	for (int i = 0; i < 26; i++){
		if (arr2[i] < arr1[i]){
			return false;
		}
	}
	return true;
}

在这里插入图片描述

4. 宝石与石头

题目链接:
771. 宝石与石头
思路分析:
??这道题很简单,我们只需要将 j 中出现的字母用下标对应的方法记录下来,然后再遍历字符串 s,计算s中有多少个属于 j 中的字母。
代码如下:

int numJewelsInStones(char * jewels, char * stones){
    int num = 0;
    int n = strlen(jewels);
    int Hash[123] = { 0 };
    //标记宝石
    for(int i = 0; i < n; i++){
        Hash[jewels[i]]++;
    }
    int m = strlen(stones);
    for(int i = 0; i < m; i++){
    	//判断是否是宝石
        if(Hash[stones[i]] > 0){
            num++;
        }
    }
    return num;
}

在这里插入图片描述

5. 判定是否互为字符重排

题目链接:
面试题 01.02. 判定是否互为字符重排
思路分析:
??这道题和之前的方法都一样,用数组将s1和s2两个字符串的字符都记录下来,如果它们的字符种类和数目都相同,则s2可以通过重新排序得到s1。
代码如下:

bool CheckPermutation(char* s1, char* s2){
    int n1 = strlen(s1);
    int n2 = strlen(s2);
    //判断特殊情况
    if(n1 != n2){
        return false;
    }
    int Hash1[123] = { 0 };
    int Hash2[123] = { 0 };
    for(int i = 0; i < n1; i++){
        //分别记录s1和s2的字符及个数
        Hash1[s1[i]]++;
        Hash2[s2[i]]++;
    }
    for(int i = 0; i < 123; i++){
        //判断字符数量是否相同
        if(Hash1[i] != Hash2[i]){
            return false;
        }
    }
    return true;
}

在这里插入图片描述

6. 检查是否所有字符出现次数相同

1941. 检查是否所有字符出现次数相同
思路分析:
??我们还是用数组的方式对字符串中的字符进行计算,并同时用一个变量记录其中某个字符的数量,然后再拿数组中的数据与其进行比较是否相同,如果出现不同的字符的数量则直接返回false。
代码如下:

bool areOccurrencesEqual(char * s){
    int arr[26] = { 0 };
    int len = strlen(s);
    int n = 0;
    for(int i = 0; i < len; i++){
        //计算每种字符的数量
        arr[s[i] - 'a']++;
        //记录某一个字符的数量
        n = arr[s[i] - 'a'];
    }
    
    for(int i = 0; i < 26; i++){
        //为0则说明没出现该字符,直接跳过
        if(arr[i] == 0){
            continue;
        }
        else if(arr[i] != n){
            return false;
        }

    }
    return true;
}

在这里插入图片描述

7. 242. 有效的字母异位词

题目链接:
242. 有效的字母异位词
这道题和判断是否为字符重排这道题的做法是一样的。
代码如下:

bool isAnagram(char * s, char * t){
    int n1 = strlen(s);
	int n2 = strlen(t);
    if(n1 != n2){
        return false;
    }
	int arr1[26] = { 0 };
	int arr2[26] = { 0 };
	for (int i = 0; i < n1; i++){
		arr1[s[i] - 'a']++;
        arr2[t[i] - 'a']++;
	}
	for (int i = 0; i < 26; i++){
		if (arr2[i] != arr1[i]){
			return false;
		}
	}
	return true;
}

在这里插入图片描述

8. 有效的变位词

题目链接:
剑指 Offer II 032. 有效的变位词

这道题和上面那道是相似的,就是多了一个条件:若 s 和 t 中每个字符出现的次数都相同且字符顺序不完全相同,则称 s 和 t 互为变位词(字母异位词)。
所以我们还需判断两个字符串是否为相同的字符串。
代码如下:

bool isAnagram(char * s, char * t){
    int n1 = strlen(s);
	int n2 = strlen(t);
    if(n1 != n2){
        return false;
    }
	int arr1[26] = { 0 };
	int arr2[26] = { 0 };
    int flag = 1;
	for (int i = 0; i < n1; i++){
        if(s[i] != t[i]){//判断是否有不相同的串
            flag = 0;
        }
		arr1[s[i] - 'a']++;
        arr2[t[i] - 'a']++;
	}
    if(flag){
        return false;
    }
	for (int i = 0; i < 26; i++){
		if (arr2[i] != arr1[i]){
			return false;
		}
	}
	return true;
}

在这里插入图片描述

9. 判断句子是否为全字母句

题目链接:
1832. 判断句子是否为全字母句
思路分析:
??题目要求是判断所给的句子是否为全字母句,而全字母句就是所有字母都至少出现过一次的句子,所以我们只需用数组记录句子中出现的字母,然后再遍历数组。

代码如下:

bool checkIfPangram(char * sentence){
    int n = strlen(sentence);
    //长度小于26的句子一定不是全字母句
    if(n < 26){
        return false;
    }
    int Hash[26] = { 0 };
    for(int i = 0; i < n; i++){
        Hash[sentence[i] - 'a']++;
    }
    for(int i = 0; i < 26; i++){
        if(Hash[i] == 0){
            return false;
        }
    }
    return true;
}

在这里插入图片描述

10. 数组中第 K 个独一无二的字符串

题目链接:
2053. 数组中第 K 个独一无二的字符串
这道题稍微有一点点难度
思路分析:
??我的解法还是比较暴力的

  1. 首先我们需要定义一个数组dp用来记录所有只出现过一次的数组的位置。
  2. 然后我们遍历所有的字符串,用strcmp进行比较,将重复出现的串用数组dp标记为0.
  3. 最后我们遍历数组dp,找到第k个未被标记的下标,然后将该下标对应的串返回即可,如果没有则返回""

代码如下:

int dp[1001];
char * kthDistinct(char ** arr, int arrSize, int k){
    //初始化数组
    memset(dp, 1, sizeof(dp));
    //遍历所有数组,并将重复出现的串标记为0
    for(int i = 0; i < arrSize; i++){
        //如果dp[i] == 0说明以及比较过了
        if(dp[i] == 0){
            continue;
        }
        for(int j = 0; j < arrSize; j++){
            if(dp[j] == 0)continue;
            if(i == j)continue;
            if(strcmp(arr[i], arr[j]) == 0){
                dp[i] = 0;
                dp[j] = 0;
            }
        }
    }
    for(int i = 0; i < arrSize; i++){
        if(dp[i]){
            k--;
        }
        if(!k){
            return arr[i];
        }
    }
    return "";
}

在这里插入图片描述

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-11-14 21:58:23  更:2021-11-14 21:59:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 10:14:24-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码