【力扣3题】快乐数&有效的字母异位词&字符串中的单词数

简介: 【力扣3题】快乐数&有效的字母异位词&字符串中的单词数

这篇文章主要是想向大家说其实力扣的好多题的解法都是很像的,我虽然刷的少,但是在这些题上都看到了熟悉的影子,就是想给大家打打鸡血吧。


题单一::202.力扣快乐数


d071a3d167a843bc89bf0f426e3a756c.png


解题思路:


快乐数就是不断求它的平方和,当某个平方和等于1时则是快乐数;


那你可能会问,一个数不断求平方和它总有可能在某一个时刻等于1吧,显然这个想法是不对的(不然为什么有快乐数的概念);


那我又要问为什么会不是快乐数呐?相信你肯定猜到了,当平方数之间产生某种循环的时候就不会得到1,解题思路就来了!


解题代码:


方法一:快慢指针法


如果不知道什么是快慢指针?传送门:快慢指针


d802ed44412f49a0a3c45089ff0909e7.png


这个快慢指针和链表那里判断环形链表有点像,因为本题也是可以通过判断是否有循环来解决


有人称作他为隐式链表,它们之间的next在此题用fun(n),该函数用来求每一十进制位的平方和来代替(next是连接两个结点的枢纽,其实fun(n)函数也是本身和他平方和数之间的枢纽)


如果有循环就是就是说明这个说明快指针和慢指针在某一个点会相遇


如果没有循环(平方和最后可以为1),快指针就会遇到1停下来


代码:

#include<stdio.h>
#include<math.h>
int fun(int n)
{
  int a[10] = { 0 };
  int len = 0;
  while (n)
  {
    a[len++] = n % 10;
    n /= 10;
  }
  int ret = 0;
  while (len--)
  {
    ret += (int)pow(a[len], 2);//强制类型转换,因为pow数学函数的返回值默认为double类型
  }
  return ret;
}
int main()
{
  int n = 0;
  scanf("%d", &n);
  int fast = n;
  int slow = n;
  while (fast != 1)//如果为1,就没有环,是快乐数
  {
    fast = fun(fast);
    fast = fun(fast);
    slow = fun(slow);
    if (slow == fast)//如果相遇,就有环
    {
      printf("该数不是快乐数\n");
      return 0;
    }
  }
  printf("该数是快乐数\n");
  return 0;
}

方法二:数学大佬


通过数学方法找到这些造成循环的数,也就是 上面环上的平方和数,但是这种方法知道就好,不用深究。


循环的数:4--->16---->37----->58----->89------->145------->42------->20 ------>4


如果有循环就是就是平方和为以上8个数


如果没有循环(平方和最后可以为1),快指针就会遇到1停下来


代码:

#include<stdio.h>
#include<math.h>
int fun(int n)
{
  int a[10] = { 0 };
  int len = 0;
  while (n)
  {
    a[len++] = n % 10;
    n /= 10;
  }
  int ret = 0;
  while (len--)
  {
    ret += (int)pow(a[len], 2);
  }
  return ret;
}
int main()
{
  int n = 0;
  scanf("%d", &n);
  int a[8] = { 4,16,37,58,89,145,42,20 };
  while (fun(n) != 1)
  {
    for (int i = 0; i < 8; i++)
    {
      if (fun(n) == a[i])
      {
        printf("该数不是快乐数\n");
        return 0;
      }
    }
    n = fun(n);
  }
  printf("该数是快乐数\n");
  return 0;
}

我想说:

快慢指针其实使用范围不局限于单链表,隐式链表同样适用。

题单二:

题目来源:242.力扣 有效的字母异位词

题目描述:


bd72f6a9d448441f8f2d8dd61215378b.png


解题思路:


字母异位词也就是两个字符串所包含的英文字母和其字母个数都是相同的;


说实话,刚开始我还打算给字母排序然后一一比较,显然这行不通


那么突然我就想到之前我在力扣上做过的一题并写了博客:剑指offer之数组中的重复元素


剑指offer之数组中的重复元素这题讲的是找出一个数组里重复的元素


edeffc1e7f394b578399849e02972a6a.png


其中我给的第二种方法:临时数组法,通过让数组元素作为一个临时数组的下标产生一种映射关系,然后遍历数组,以数组元素值为下标的临时数组就对应+1来计数,遍历完后通过临时数组哪些元素为2,就对应返回这个临时数组的下标即可.


举个例子:


8bcea677000f4297acf43dff8690d28d.png


本题同样可以使用这种方法,因为题目说字母都是小写字母,那么对应开辟两个临时数组,每一个临时数组元素个数就定位26,遍历完两个数组后就产生两种映射关系,然后两个临时数组元素值比较大小就代表字符出现的个数.


代码:

#include<stdio.h>
int main()
{
  char str1[] = "hello";
  char str2[] = "lolex";
  int len1 = strlen(str1);
  int len2 = strlen(str2);
   //如果长度都不相等,那一定不是有效的字母异位词
  if (len1 != len2)
  {
    printf("否\n");
    return 0;
  }
    //开辟两个临时数组
  int temp1[26] = { 0 };
  int temp2[26] = { 0 };
  //产生映射关系
  for (int i = 0; i < len1; i++)
  {
    temp1[str1[i]-'a']++;
  }
  for (int i = 0; i < len2; i++)
  {
    temp2[str2[i]-'a']++;
  }
    //比较是否有该字符元素且个数是否相等
  for (int j = 0; j < 26; j++)
  {
    if (temp1[j] != temp2[j])
    {
      printf("否\n");
      return 0;
    }
  }
  printf("是\n");
  return 0;
}

题单三:


题目描述:434. 【力扣】字符串中的单词数


6a2caec083724498919c17d0c330effe.png


题解思路:


我猜你之前肯定和我一样,打算计算空格的个数来得出单词的个数,但是每一个单词的前后可能有空格,也可能只有一个空格,所以这个思路根本行不通!再者说可以多个空格连在一起组成“空格串”


fcb1e687d34142998688836d0463a71e.png


其实我们可以遍历一遍字符串,以空格结尾和字符串的开头的连接的个数作为单词的个数

9122cd9f6c9e43f9b95f1b4cc992a9d0.png

#include<stdio.h>
#include<string.h>
int main()
{
  char str[] = " can you do it?  ";
  int len = strlen(str);
  int count = 0;//求单词个数
  for (int i = 0; i<len; i++)
  {
    while (i < len && str[i] == ' ')
    {
      i++;
    }
    if(i<len)
      count++;
    while (i < len && str[i] != ' ')
    {
        i++;
     }
  }
  printf("%d\t", count);
}

或者这样:

#include<stdio.h>
#include<string.h>
int main()
{
  char str[] = " can you do it?  ";
  int len = strlen(str);
  int count = 0;//求单词个数
  for (int i = 1; i < len; i++)//从1开始
{
  if ((str[i] == ' ' || str[i] == '\0') && str[i - 1] != ' ')
    count++;
}
    printf("%d\t", count);
}
目录
相关文章
|
1月前
|
存储 算法
LeetCode第49题字母异位词分组
LeetCode第49题"字母异位词分组"的解题方法,通过将每个字符串的字符排序后作为键存储在HashMap中,有效地将所有字母异位词分组。
LeetCode第49题字母异位词分组
|
1月前
|
存储 算法
LeetCode第43题字符串相乘
LeetCode第43题"字符串相乘"的解题方法,通过使用数组存储乘积并处理进位,避免了字符串转换数字的复杂性,提高了算法效率。
LeetCode第43题字符串相乘
|
1月前
|
算法 Java
LeetCode第28题找出字符串中第一个匹配项的下标
这篇文章介绍了LeetCode第28题"找出字符串中第一个匹配项的下标"的两种解法:暴力解法和KMP算法,并解释了KMP算法通过构建前缀表来提高字符串搜索的效率。
LeetCode第28题找出字符串中第一个匹配项的下标
|
1月前
|
算法
LeetCode第17题电话号码的字母组合
该文章介绍了 LeetCode 第 17 题电话号码的字母组合的解法,通过分析得出可使用递归和回溯的思想解决,避免循环穷举的高循环次数,并给出了具体的编码实现,同时总结了该题较难理解,需要了解递归的本质,当嵌套循环层次多时可考虑递归。
LeetCode第17题电话号码的字母组合
|
1月前
|
算法
LeetCode第8题字符串转换整数 (atoi)
该文章介绍了 LeetCode 第 8 题字符串转换整数 (atoi)的解法,需要对字符串进行格式解析与校验,去除前导空格和处理正负号,通过从高位到低位的计算方式将字符串转换为整数,并处理越界情况。同时总结了这几道题都需要对数字的表示有理解。
LeetCode第8题字符串转换整数 (atoi)
|
3月前
|
算法
力扣每日一题 6/23 字符串/模拟
力扣每日一题 6/23 字符串/模拟
30 1
|
3月前
|
索引
力扣每日一题 6/27 字符串 贪心
力扣每日一题 6/27 字符串 贪心
27 0
|
3月前
|
Python
力扣随机一题 模拟+字符串
力扣随机一题 模拟+字符串
24 0
|
3月前
力扣每日一题 6/22 字符串/贪心
力扣每日一题 6/22 字符串/贪心
23 0
|
3月前
力扣每日一题 6/18 字符串/模拟
力扣每日一题 6/18 字符串/模拟
21 0