字母异位词 分析:(1)本题主要是ASCII码(计算机本质是要存放二进制数,ASCII码就是统一规定了常用符号用哪些二进制数来表示)主要记住字符a到字符z的ASCII是26个连续的数值,用一个值去减去’a’,映射下标为0,相应的字符z映射为下标25,得到一个相对数值可以帮我们实现题目即可。
(2)通过数组统计不同字母出现的次数,当s中出现的字母我们就++,t中出现的字母我们就–,最后如果数组中还有值,说明有多余的字母,返回false。
public class Solution {
public bool IsAnagram(string s, string t) {
if(s.Length != t.Length) return false;
int[] arr = new int[26];
for(int i = 0;i < s.Length; i++)
{
arr[s[i] - 'a']++;
arr[t[i] - 'a']--;
}
foreach(var v in arr)
{
if(v != 0)
return false;
}
return true;
}
}
数组交集 分析:本题使用HashSet,碰到交集并集等,都有对应的方法,IntersectWith就是求交集。
public class Solution {
public int[] Intersection(int[] nums1, int[] nums2) {
HashSet<int> hs1 = new HashSet<int>();
HashSet<int> hs2 = new HashSet<int>();
for(int i = 0; i < nums1.Length; i++)
{
hs1.Add(nums1[i]);
}
for(int j = 0; j < nums2.Length; j++)
{
hs2.Add(nums2[j]);
}
hs1.IntersectWith(hs2);
return hs1.ToArray();
}
}
快乐数 分析:(1)这道题看着不难,做的时候答案都看不懂,主要还是个人思想太重了,其实仔细看看就是平方那里的问题罢了
(2)如果你看到本题也很吃力,我还是建议多看多写,每次遇到类似的问题能有一个思路写就好
(3)不重要的解析就不说了,就是出现过的数字如果再次出现,说明就是个闭环,下次也会出现,那这种情况直接return false就好了
(4)HashSet就是用来存储出现过的元素
接下来逐行讲解,保证是个人都会看懂!!!
public class Solution {
public bool IsHappy(int n) {
HashSet<int> hs1 = new HashSet<int>();
//while循环 条件其实就是围绕题目的相反方向
while(n != 1)
{
//一个总和变量 用来求总值
int sum = 0;
//这个while循环呢 就是处理数字平方和的
//像这里 我选择记住 做到能理解 能有印象 我觉得就行了
//不用怕下次写不出来 写不出来继续多写两次
while(n > 0)
{
//其实就是sum先添加个位元素的平方 然后将n缩小10倍 在添加一轮
//比如n = 19,那么sum就是81,n = 19/10 = 1
//n > 0 所以再来一轮sum= 81 + 1%10 = 82 ,n = 0 结束
//如果n缩小10倍后小于0 说明是单数
sum += (n % 10) * (n % 10);//9*9 2*2
n /= 10;//1 0
}
//如果总和 = 1 说明符合题意
if(sum == 1)
{
return true;
}
//如果包括了这个数 说明之前添加过 是个闭环 那就false
if(hs1.Contains(sum))
{
return false;
}
//如果无事发生就到最后这步
//hashSet中添加该值
hs1.Add(sum);
//同时需要让n更新一下最新值 才能进入下一个循环
n = sum;
}
return true;
}
}
两数之和 分析:力扣的启蒙题了算是,本次我们不用暴力,使用哈希表来解决
(1)就是通过字典存储已经出现过的元素,检查看看是否有相加就可以等于target的数,具体看代码
(2)字典中Key就代表元素本身,Value就是它的下标
public class Solution {
public int[] TwoSum(int[] nums, int target) {
Dictionary<int,int> numDic = new Dictionary<int,int>();
for(int i = 0; i < nums.Length; i++)
{
//示例一中 我们的目标值是9,在第一次进入循环时,nums[i]是2,
//首先用一个临时变量记录一下它相加可以等于target的值 temp = 7
//很明显没有对吧 那我们就把2添加到字典中,Value记录的是他的下标
//第二次我们进入循环 这时nums[i] = 7了,temp = 2
//那2刚存过对吧
int temp = target - nums[i];
if(numDic.ContainsKey(temp))
{
//这时就根据题意返回7的下标和2的下标 即可
return new int[]{i, numDic[temp]};
}
numDic.Add(nums[i],i);
}
return new int[]{0,0};
}
}
四数相加 || 分析:题目就是算四个数组相加的结果等于0的次数,本题选择使用数组来实现,将前两个数组相加作为1次计算,后两个数组相加作为1次计算,
(1)将第一次计算的结果添加到字典中,Key为值,Value为值的数量
(2)对第二次计算的结果进行判断,将结果为负,因为题目要求是相加等于0,假设第一次计算的结果等于-1,那么第二次计算的结果要等于1,但是字典中添加的元素是-1,所以要将结果取负进行判断
public class Solution {
public int FourSumCount(int[] nums1, int[] nums2, int[] nums3, int[] nums4) {
Dictionary<int,int> sumDic = new Dictionary<int,int>();
for(int i = 0; i < nums1.Length; i++)
{
for(int j = 0; j < nums2.Length; j++)
{
int sum = nums1[i] + nums2[j];
if(sumDic.ContainsKey(sum))
{
//存在我们就对Value进行++
sumDic[sum]++;
}
else
{
//不存在我们就添加一个元素和它的数量1
sumDic.Add(sum,1);
}
}
}
int count = 0;
for(int i = 0; i < nums3.Length; i++)
{
for(int j = 0; j < nums4.Length; j++)
{
//对结果进行取反 因为要和字典中的值一致 两次计算的sum相加等于0
int sum = -(nums3[i] + nums4[j]);
if(sumDic.ContainsKey(sum))
{
//这里要注意,假设字典中有(-1,2)
//什么意思呢 就是key = -1,数量为2对吧
//那在本次运算中 判断存在数字-1 如果直接count++ 那就会少一个数量
//所以要记得 += Value 即可
count += sumDic[sum];
}
}
}
return count;
}
}
赎金信 分析:这种涉及到字母之间比较的,第一反应不是字典就是26数组(通过ASCII码记录相对值)
(1)通过一个数组记录一个字符串中各个元素出现的次数
(2)遍历第二个字符串,如果有元素的数量是小于0的,说明不满足
public class Solution {
public bool CanConstruct(string s, string t) {
int[] arr = new int[26];
foreach(var v in t)
{
//看不懂就再去看一下ASCII码 其实知道减去'a'得到的一个个相对值 能够帮助我们记录就行
arr[v - 'a']++;
}
foreach(var v in s)
{
arr[v - 'a']--;
//假设t字符串中的字符a数量为1,但s中字符a数量为2,上述两次--就是-1了
if(arr[v - 'a'] < 0)
{
return false;
}
}
return true;
}
}