首页 > 其他分享 >简单总结最近力扣所刷的题

简单总结最近力扣所刷的题

时间:2023-06-16 20:32:05浏览次数:45  
标签:总结 前缀 nums int 三元组 力扣 所刷 数组 字符串

下面的题目是最近我在力扣上面刷了每日一题之后所做的总结。

题目一

比较字符串最小字母出现频次

定义一个函数 f(s),统计 s  中(按字典序比较)最小字母的出现频次 ,其中 s 是一个非空字符串。

例如,若 s = "dcce",那么 f(s) = 2,因为字典序最小字母是 "c",它出现了 2 次。

现在,给你两个字符串数组待查表 queries 和词汇表 words 。对于每次查询 queries[i] ,需统计 words 中满足 f(queries[i]) < f(W) 的 词的数目 ,W 表示词汇表 words 中的每个词。

请你返回一个整数数组 answer 作为答案,其中每个 answer[i] 是第 i 次查询的结果。

示例 1:

输入:queries = ["cbd"], words = ["zaaaz"]
输出:[1]
解释:查询 f("cbd") = 1,而 f("zaaaz") = 3 所以 f("cbd") < f("zaaaz")。

示例 2:

输入:queries = ["bbb","cc"], words = ["a","aa","aaa","aaaa"]
输出:[1,2]
解释:第一个查询 f("bbb") < f("aaaa"),第二个查询 f("aaa") 和 f("aaaa") 都 > f("cc")。

这道题目主要难度在我看来是理解题意,如果不给你示例的话,是很难理解这道题目在干嘛的。而看了示例之后就很好理解了。首先你求出queries数组中每一个字符串最小字母出现的次数,然后和words中每一个字符串出现的最小字母次数比较,输出words中有多少字符串的最小字母出现的次数大于queries中的字符串。那么思路也就有了首先我们先完成一个函数函数的作用为计算一个字符串中最小字母出现的次数。

计算字符串中最小字母出现次数的函数:

int Get_des(char* arr) {
    char smaller = 'z'; // 先设定最小的字符为 z
    int i = 0;
    int count = 0;
    while (arr[i]) {
        if (arr[i] < smaller) {
            smaller = arr[i];
            count = 1;
        } else if (arr[i] == smaller) {
            count++;
        }
        i++;
    }
    return count;
}

之后的思路也就是创建一个数组储存words数组中每一个字符串中最小字母的出现次数。再创建一个数组用于储存答案,这个答案数组的长度也很简单,queries中含有多少个字符串那么答案数组就有多大的长度。然后我们遍历queries数组为答案数组赋值

int* numSmallerByFrequency(char ** queries, int queriesSize, char ** words, int wordsSize, int* returnSize){
    int* ret = (int*)malloc(sizeof(int)*queriesSize);//创建用于返回的答案数组
    memset(ret,0,sizeof(int)*queriesSize);//将里面的值初始化为0
    int wordscount[wordsSize];//这个数组用于储存words每一个字符串中最小字符出现的次数
    for(int i = 0;i<wordsSize;i++)
    {
        wordscount[i] = get_des(words[i]);
        //为wordscount数组赋值
    }
    for(int i = 0;i<queriesSize;i++)
    {
        int queriescount = get_des(queries[i]);//这个常量用于储存queries数组中每一个字符串
        //最小字母出现的次数
        for(int k = 0;k<wordsSize;k++)
        {
            if(wordscount[k]>queriescount)
            ret[i]++;//如果words数组中出现了最小字母出现次数大于
            //这个queries字符串中最小字母出现次数的情况
            //那就让答案数组中的次数加1
        }
    }
    *returnSize = queriesSize;
    return ret;
}

做题链接:1170. 比较字符串最小字母出现频次 - 力扣(Leetcode)

题目二:

1171. 从链表中删去总和值为零的连续节点

给你一个链表的头节点 head,请你编写代码,反复删去链表中由 总和 值为 0 的连续节点组成的序列,直到不存在这样的序列为止。

删除完毕后,请你返回最终结果链表的头节点。

 

你可以返回任何满足题目要求的答案。

(注意,下面示例中的所有序列,都是对 ListNode 对象序列化的表示。)

示例1:

输入:head = [1,2,-3,3,1]
输出:[3,1]
提示:答案 [1,2,1] 也是正确的。

示例2:

输入:head = [1,2,3,-3,4]
输出:[1,2,4]

示例3:

输入:head = [1,2,3,-3,-2]
输出:[1]

这道题要怎么解决呢?最简单的做法也就是找到原链表中子链和为0的情况将这条子链删除即可,那么首先寻找子链,因为有可能会删除第一个节点,为了方便可以添加一个哨兵卫。

下面是代码实现:

struct ListNode* removeZeroSumSublists(struct ListNode* head){
       struct ListNode* newhead = (struct ListNode*)malloc(sizeof(struct ListNode));
       newhead->val = 0;
       newhead->next = head;
       struct ListNode* cur = newhead;//用于确定子链的头节点
       int x = 0;
       while(cur)
       {
           struct ListNode* p = cur->next;//遍历寻找子链
           while(p)
           {
              x = x+p->val;
              if(x == 0)
              {
                  cur->next = p->next;//删除和为0的子链
              }
              p = p->next;//遍历完这一条子链
           }
           //进行到这里就判完一条子链了,去判断下一条子链
           x = 0;//重新为下一条子链,初始化判断条件
            cur = cur->next;
       }
       return newhead->next;
}

做题链接:1171. 从链表中删去总和值为零的连续节点 - 力扣(Leetcode)

题目三

2475. 数组中不等三元组的数目

给你一个下标从 0 开始的正整数数组 nums 。请你找出并统计满足下述条件的三元组 (i, j, k) 的数目:

  • 0 <= i < j < k < nums.length
  • nums[i]nums[j] 和 nums[k]两两不同 。
  • 换句话说:nums[i] != nums[j]nums[i] != nums[k] 且 nums[j] != nums[k] 。

返回满足上述条件三元组的数目

示例1:

输入:nums = [4,4,2,4,3]
输出:3
解释:下面列出的三元组均满足题目条件:
- (0, 2, 4) 因为 4 != 2 != 3
- (1, 2, 4) 因为 4 != 2 != 3
- (2, 3, 4) 因为 2 != 4 != 3
共计 3 个三元组,返回 3 。
注意 (2, 0, 4) 不是有效的三元组,因为 2 > 0 。

示例2:

输入:nums = [1,1,1,1,1]
输出:0
解释:不存在满足条件的三元组,所以返回 0 。

对于这道题目因为力扣所给的数组大小很小,所以第一种方法也就是直接暴力遍历,三个循环寻找符合条配件的三元组

方法一

int unequalTriplets(int* nums, int numsSize)
{
    int count = 0;
    //方法一:三重循环暴力查找
    for(int i = 0;i<numsSize;i++)//一重循环寻找第一个数
    {
        for(int j = i+1;j<numsSize;j++)//二重循环寻找第二个数
        {
            for(int k = j+1;k<numsSize;k++)//三重循环寻找第三个数
            {
                if(nums[i]!=nums[j]&&nums[j]!=nums[k]&&nums[i]!=nums[k])
                {
                    count++;//符合条件让计数器加1
                }
            }
        }
    }
    return count;//返回计数器值
}

思路二:可以寻找三个不同的元素数量,让数量相乘,那么就能得到这三个元素所能组成的所有三元组可能性,遍历数组找到所有的三元组数量

int compare(const void* p1,const void* p2)
{
    return *(int*)p1 - *(int*)p2;
}
int unequalTriplets(int* nums, int numsSize){
    qsort(nums,numsSize,sizeof(int),compare);//先将原数组排序完成
    int count = 0;
    for(int i = 0,j = 0;i<numsSize;i=j)//这里i的变化为什么是让i变成j,下面我会做出解释
    {
        while(j<numsSize&&nums[j] == nums[i])
        {
            j++;
        }
        count += i*(j-i)*(numsSize-j);
        /*由题意可知,数组元素的相对顺序不影响结果,因此我们可以将数组  
        //从小到大进行排序。排序后,数组中的相同元素一定是相邻的。
        //当我们以某一堆相同的数 [i,j)作为三元组的中间元素时,
        //这堆相同的元素的左边元素数目为 i,右边元素数目为 n−j,
        //那么符合条件的三元组数目为(i*(j-i)*(n-j)),这里的n也就是numsSize
    }
    return count;
}

做题链接:2475. 数组中不等三元组的数目 - 力扣(Leetcode)

题目四

1375. 二进制字符串前缀一致的次数

给你一个长度为 n 、下标从 1 开始的二进制字符串,所有位最开始都是 0 。我们会按步翻转该二进制字符串的所有位(即,将 0 变为 1)。

给你一个下标从 1 开始的整数数组 flips ,其中 flips[i] 表示对应下标 i 的位将会在第 i 步翻转。

二进制字符串 前缀一致 需满足:在第 i 步之后,在  区间 [1, i] 内的所有位都是 1 ,而其他位都是 0 。

返回二进制字符串在翻转过程中 前缀一致 的次数。

 示例 1:

输入:flips = [3,2,4,1,5]
输出:2
解释:二进制字符串最开始是 "00000" 。
执行第 1 步:字符串变为 "00100" ,不属于前缀一致的情况。
执行第 2 步:字符串变为 "01100" ,不属于前缀一致的情况。
执行第 3 步:字符串变为 "01110" ,不属于前缀一致的情况。
执行第 4 步:字符串变为 "11110" ,属于前缀一致的情况。
执行第 5 步:字符串变为 "11111" ,属于前缀一致的情况。
在翻转过程中,前缀一致的次数为 2 ,所以返回 2 。

示例 2:

输入:flips = [4,1,2,3]
输出:1
解释:二进制字符串最开始是 "0000" 。
执行第 1 步:字符串变为 "0001" ,不属于前缀一致的情况。
执行第 2 步:字符串变为 "1001" ,不属于前缀一致的情况。
执行第 3 步:字符串变为 "1101" ,不属于前缀一致的情况。
执行第 4 步:字符串变为 "1111" ,属于前缀一致的情况。
在翻转过程中,前缀一致的次数为 1 ,所以返回 1 。

这道题也就是给了你一个足够大的字符串(全0),然后给了你一个数组,数组里面的数字代表接下来字符串中的哪一个数字会从0变成1,然后题目要求你返回在翻转过程中有多少次前面数字全是1,后面数字全是0的情况。

这道题要求在经历第i次翻转之后,字符串中第1到i卫的数字都为1,这其实也就等价于前i次翻转中下标的最大值也就是i。

我先将代码写出来,之后举一个例子

int numTimesAllBlue(int* flips, int flipsSize)
{
    int count = 0;//用于计算次数
    int right = 0;//用以记录现在已经出现的最大下标为多少
    for(int i = 0;i<flipsSize;i++)
    {
        right = fmax(right,flips[i]);//这里的fmax是一个比较大小函数,但这个函数最后返回的其实一个浮点数
        //这里强制转化为int,在某些情况会出现数值错误
        if(right == i+1)
        {
            count++;//这里也就是出现了前缀一致的情况了
        }
    }
    return count;
}

举一个例子最容易理解:

简单总结最近力扣所刷的题_字符串

做题链接:1375. 二进制字符串前缀一致的次数 - 力扣(Leetcode)

我现在还只是一个还在成长的小小萌新,如果有错误请各位大佬见谅。





标签:总结,前缀,nums,int,三元组,力扣,所刷,数组,字符串
From: https://blog.51cto.com/u_15838996/6502496

相关文章

  • SSM三层架构流程总结
    1.搭环境webapp\WEB-INF\web.xmlpom里面激活webapp<packaging>war</packaging>将pom坐标复制web.xml复制进去配置文件resources目录引入applicationContext.xmljdbc.propertieslog4j.propertiesspring-mvc.xml2.创建实体类层com.msr.bean实体类.class命名规则......
  • 迭代器与生成器总结
    参考《JavaScript高级程序设计》迭代是一种所有编程语言中都可以看到的模式。ECMAScript6正式支持迭代模式并引入了两个新的语言特性:迭代器和生成器。迭代器是一个可以由任意对象实现的接口,支持连续获取对象产出的每一个值。任何实现Iterable接口的对象都有一个Symbol.iterato......
  • k8s 梳理及使用总结
    ---1.Kubernetes概述1.最初Google开发了1个叫Borg的系统(现在命名为Omega),来调度近20多亿个容器从2014年第1个版本发布以来,迅速得到了开源社区的追捧,?前,k8s已经成为了发展最快、市场占有率最高的容器编排引擎产品。---2.特点轻量级,资源消耗小开源弹性伸缩负载均衡IPVS---3......
  • Go-map、切片、数组循环常见问题总结
    map1、forrangemap在开始执行循环的时候,底层做了随机种子,故其循环是随机的。packagemainimport"fmt"funcmain(){ a:=map[int]int{0:1,1:2,2:3,3:4,4:5} for_,c:=rangea{ fmt.Println(c) }}输出:34512多次执行,结果不同数组packagema......
  • File I/O学习总结
    1.File文件的增删查(1)增publicvoidaddFile(Filefile){file.createNewFile();}(2)删publicvoiddeleteFile(Filefile){file.delete();}(3)查publicvoidfindFile(Filefile){file.getName();file.getAbsolutePath();}2.流的指向(1)读入【文件读入到......
  • 力扣---1177. 构建回文串检测
    给你一个字符串 s,请你对 s 的子串进行检测。每次检测,待检子串都可以表示为 queries[i]=[left,right,k]。我们可以重新排列子串 s[left],...,s[right],并从中选择最多k 项替换成任何小写英文字母。 如果在上述检测过程中,子串可以变成回文形式的字符串,那么检测结......
  • 【JS错题总结】关于上下文
    <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>Title</title></head><body><script>functionfunc1(){console.log(1,this.value)}......
  • 第三次博客:PTA题目集6-8总结
    第三次博客:PTA题目集6-8总结 前言:菜单系列终于结束了,但是接踵而至的是全新的选课系列,明明JAVA课都已经上完了,但是大作业的更新却并没有停止,由此可见蔡老师真的太爱我们了。这次的选课系统个人感觉是和点菜大同小异的,菜单==课表,选课==点菜,算......
  • 思维总结
    方法找出满足要求的最大值和最小值,考虑从最小值逐渐向最大值调整,或从最大值逐渐向最小值调整。找出一种特殊情况下的方案,在考虑把其它情况变成这种特殊情况。或者把其它情况分成多个这种特殊情况。有些构造题,考虑按照一定顺序放物品,然后发现如果当前点能放但不放,后面一定......
  • 2023-6-15 面试笔试复盘总结
    四川君迪能源后端笔试2023-6-15简答题:线程和进程的区别本质区别:进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位。包含关系:一个进程至少有一个线程,线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程。资源开销:每个进程都有独立的地址空......