这题在开营前琢磨过,复习了一下,leetcode上记了笔记,就直接抄过来了
第一次解答忘记了在判断长度是否相等后,长度不相等可以直接返回false,不需要往下判断了。
没通过的原因,有部分是因为不熟悉C++的使用,一些功能不知道怎么调用。
最简单的办法是暴力破解,用双重循环遍历,同时记录下相同字母的字母数量,时间复杂度是O(n^2).
看了其他人的题解得到的收获:
先排序再判断长度,长度不等就false.
定义数组的方法可以是,将字符串以每个字符分别放进数组
char[]str1 = s.toCharArray();
char[]str2 = t.toCharArray();
其中的s是一个已知的字符串。
数组排序可以是直接用Array.sort函数对数组str1和数组str2进行排序
Array.sort(str1);
Array.sort(str2);
哈希表的本质是数组,我们就定义一个大小为26的数组,对应值初始化为0,用来记录每个小写字母出现的次数,先遍历s当该字母出现一次就+1,再遍历,出现一次就-1,最后判断是否都为0,如果是,那么s和t就是彼此的异位字母。
使用数组元素对字母进行计数时,考虑用当前字母的ASCII码减去‘a’,也就是减去96,这样可以得到26个小写字母从0--25的索引所对应的位置,可以节省空间。
int record[26]={0};
for(int i=0;i
判断两个字符串是否相等可以使用函数Array.equals
返回值是bool型,可能是false或true.
Arrays.equals(str1,str2);
class Solution {
public:
bool isAnagram(string s, string t) {
if(s.length()!=t.length()){return false;}
int record[26]={0};
for(int i=0;i
使用数组做哈希表是因为题目限制了数值的大小,当不再限制数值的大小时,就无法使用数组来做哈希表。如果哈希值比较小、特别分散、跨度很大,就会造成数组空间浪费。这时选择set.
set在C++中有3种可用的数据结构,std::set ; std::multiset ; std::unordered_set ;
std::set和std::multiset底层实现是红黑树,std::unordered_set的底层实现是哈希表。
这题使用std::unordered_set,它读写效率最高,无需排序,数据不重复。
这题不涉及太复杂的算法,只要用一个循环遍历,找出同时出现在num1和num2中的数即可。用set是为了使数据不重复。
将一个普通数组转化成unordered_set 形式,使用nums_set(Arrays.begin(),Arrays.end());
unordered_setnums_set(nums1.begin(),nums1.end());//将数组nums1变成unordered_set类型
求解的源代码:
class Solution {
public:
vector intersection(vector& nums1, vector& nums2) {
unordered_set result_set;
unordered_setnums_set(nums1.begin(),nums1.end());
for(int num:nums2)
{
if(nums_set.find(num) !=nums_set.end()){
result_set.insert(num);
}
}
return vector(result_set.begin(),result_set.end());
}
};
set的直接使用不仅空间比数组大,而且速度比数组慢,set把数值映射到key上都要做hash计算的。在数量大的情况下,差异会很显著。
原题链接leetcode202快乐数
题目要求将正整数的每位的数字平方求和,有和为1就true,无则继续找,至sum重复出现,false.
可以写一个函数对数值各个位上的单数之和进行求解
int getSum(int n){
int sum = 0;
while(n){
sum += (n % 10)*(n % 10);//对一个整数取余,得到的是个位数
n/=10;
}
return sum;
}
使用set求解,设置一个unordered_set的容器set,只要判断出当前的sum不在set里,就将这个sum通过insert()函数添加到set,每得到一个sum,就执行一次判断,直到出现和set容器内存放的值相等的sum,就返回false.结束循环,这种方式来判断sum是否重复出现。
unordered_setset;
while(1){
int sum = getsum(n);//调用getsum()求sum的函数
if(sum == 1){
return true;
}
if(set.find(sum) != set.end()){
return false; //重复了,直接返回false
}else{
set.insert(sum);//将没有重复的sum插入进set
}
n = sum;
}
完整求解代码如下:
class Solution {
public:
int getsum(int n){
int sum = 0;
while(n)
{
sum += (n % 10) * (n % 10);
n /= 10;
}
return sum;
}
bool isHappy(int n) {
unordered_setset;
while(1){
int sum = getsum(n);
if(sum == 1){
return true;
}
if(set.find(sum) != set.end()){
return false;
}else{
set.insert(sum);
}
n=sum;
}
}
};
原题链接:1.两数之和
[关于map]map分三种,std::map和std::mutimap底层是红黑树,std::unoredered_map底层是哈希表。
map有两个值value和key,value是数组元素下标,key是数组元素。
遍历数组时,向map去查询是否有与当前被遍历到的元素相同的数值,有,就找到对应的key和value,没有就把这个被遍历到的元素放进map,这里和前一个题目unordered_set的set思路一样。
在定义mao时记得map中是key和value两个值,所以应用
std::unordered_mapmap;
对数组遍历,找和map中某个元素相同的元素,如果有就返回value和key,如果没有,就把它的value,key通过insert()函数记录进map。
map.insert(pair(nums[i],i));
完整求解代码如下:
class Solution {
public:
vector twoSum(vector& nums, int target) {
std::unordered_mapmap;
for(int i = 0;i < nums.size();i++)
{
auto iter = map.find(target - nums[i]);
if(iter != map.end()){
return{iter->second,i};
}
map.insert(pair(nums[i],i));
}
return{};
}
};