【力扣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);
}
目录
相关文章
|
4月前
|
存储 算法
LeetCode第49题字母异位词分组
LeetCode第49题"字母异位词分组"的解题方法,通过将每个字符串的字符排序后作为键存储在HashMap中,有效地将所有字母异位词分组。
LeetCode第49题字母异位词分组
|
2月前
|
JavaScript
力扣3333.找到初始输入字符串Ⅱ
【10月更文挑战第9天】力扣3333.找到初始输入字符串Ⅱ
37 1
|
2月前
|
C++
Leetcode第43题(字符串相乘)
本篇介绍了一种用C++实现的字符串表示的非负整数相乘的方法,通过逆向编号字符串,将乘法运算转化为二维数组的累加过程,最后处理进位并转换为字符串结果,解决了两个大数相乘的问题。
25 9
|
2月前
|
存储
Leetcode第49题(字母异位词分组)
LeetCode第49题要求将字符串数组中的字母异位词分组,可以通过将每个字符串排序后作为键存入哈希表,最后将哈希表中的值添加到结果列表中来实现。
17 1
|
2月前
|
算法
Leetcode第十七题(电话号码的字母组合)
这篇文章介绍了如何使用深度优先搜索(DFS)算法来解决LeetCode第17题——电话号码的字母组合问题,通过递归方法生成所有可能的字母组合。
23 0
Leetcode第十七题(电话号码的字母组合)
|
2月前
|
索引
【LeetCode 11】242.有效的字母异位词
【LeetCode 11】242.有效的字母异位词
19 0
【LeetCode 11】242.有效的字母异位词
|
2月前
|
算法
【LeetCode 52】17.电话号码的字母组合
【LeetCode 52】17.电话号码的字母组合
42 0
|
2月前
|
算法 C++
Leetcode第八题(字符串转换整数(atoi))
这篇文章介绍了LeetCode上第8题“字符串转换整数(atoi)”的解题思路和C++的实现方法,包括处理前导空格、正负号、连续数字字符以及整数溢出的情况。
20 0
|
2月前
【LeetCode 22】459.重复的子字符串
【LeetCode 22】459.重复的子字符串
30 0
|
2月前
【LeetCode 20】151.反转字符串里的单词
【LeetCode 20】151.反转字符串里的单词
21 0