当前位置: 首页 > news >正文

菜鸟刷题Day5

⭐作者:别动我的饭
⭐专栏:菜鸟刷题
⭐标语:悟已往之不谏,知来者之可追
在这里插入图片描述

一.一维数组的动态和:1480. 一维数组的动态和 - 力扣(LeetCode)

描述

给你一个数组 nums 。数组「动态和」的计算公式为:runningSum[i] = sum(nums[0]…nums[i]) 。

请返回 nums 的动态和。

示例:

输入:nums = [1,2,3,4]
输出:[1,3,6,10]
解释:动态和计算过程为 [1, 1+2, 1+2+3, 1+2+3+4] 。

解题思路

1.通过观察示例可以发现,其实runningSum[0]和nums[0]相等,runningSum[1]=runningSum[0]+nums[1];所以我们可以得到这样一个结论:当 i > 0时:runningSum[i]=runningSum[i-1]+nums[i];

我可以新开辟一个数组(大小和nums一样大),将累加的结果存放到这个新开的数组中,再返回这个新开辟的数组。

int* runningSum(int* nums, int numsSize, int* returnSize)
{	
    int*tmp=(int*)malloc(sizeof(int)*numsSize);
    tmp[0]=nums[0];
    
    for(int i=1;i<numsSize;i++)
    {
        tmp[i]=tmp[i-1]+nums[i];
    }
    *returnSize=numsSize;
    
    return tmp;
}

2.直接在原地改变,除了第一项不用改变以外,后面的每一项元素都是前面元素累加的结果。

int* runningSum(int* nums, int numsSize, int* returnSize)
{
    for(int i=1;i<numSize;i++)
    {
         nums[i]+=nums[i-1];
    }
    
    *returnSize=numsSize;
    
    return nums;
}

二.搜索插入位置:35. 搜索插入位置 - 力扣(LeetCode)

描述

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

请必须使用时间复杂度为 O(log n) 的算法。


解题思路

看到说时间复杂度位O(log n)就让人想起二分查找算法,二分查找虽然强大,但是有一个很大的缺陷就是要求被查找的数据必须要有序。正好题目说了是一个排序数组,那还不二分走起

int searchInsert(int* nums, int numsSize, int target)
{
    int begin=0;
    int end=numsSize-1;
    int mid=0;
    
    while(begin<=end)
    {
        mid=(begin+end)/2;
        
        if(nums[mid]<target)
        {
            begin=mid+1;
        }
        else if(nums[mid]>target)
        {
            end=mid-1;
        }
        else//相等
        {
            return mid;
        }
        

    }
   return begin;
}

关于最后的返回值:位于begin左边的数一定小于目标值,而在end右边的数一定是大于end的,也就是说目标值要么在begin和end的中间,要么就在begin和end之间的某个位置插入,而最后的结束条件是begin>end,也就是说这中间只有begin是一直在改变的,因此如果最后在数组中找不到这个元素,那么它的插位置一定是begin位置


三.搜索旋转排序数组:33. 搜索旋转排序数组 - 力扣(LeetCode)

描述

整数数组 nums 按升序排列,数组中的值 互不相同 。

在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], …, nums[n-1], nums[0], nums[1], …, nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。

给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。

你必须设计一个时间复杂度为 O(log n) 的算法解决此问题。


解题思路

首先映入眼帘的还是O(log n),那么用二分查找吗?一看是升序排序数组,但是这里又说了,会在某个位置旋转一下。好像不能用二分

但是(我知道你在等但是),在k位置旋转以后,仍然是局部有序的。如果中间的数小于最右边的数,则右半段是有序的,若中间数大于最右边数,则左半段是有序的,我们只要在有序的半段里用首尾两个数组来判断目标值是否在这一区域内,这样就可以确定保留哪一半了

这里只要通过控制下标就可以实现在一个数组内分割出两个数组的目的

int search(int* nums, int numsSize, int target)
{
    //核心在于只是局部有序

    int begin=0,end=numsSize-1;
    while(begin<=end)
    {
        int mid=(begin+end)/2;

        if(nums[mid]==target)
            return mid;

        //二分查找只能在有序数列中进行,所以要判断有序范围,一定是局部有序
        if(nums[mid]<nums[end])//说明右边数组有序
        {
            //判断一下目标值是否在右边数组中,既然在右边数组,那么就要重新调整一下mid的值
            if(nums[mid]<target&&nums[end]>=target)
                 begin=mid+1;
            else
                end=mid-1;      
        }
        else
        {
            //左边数组有序,还要判断一下是否在左边数组中
            if(nums[mid]>target&&nums[begin]<=target)
                end=mid-1;
            else
                begin=mid+1;
        }

    }
    //到这里就是找不到
    return -1;
}

四.二进制链表转整数:1290. 二进制链表转整数 - 力扣(LeetCode)

描述

给你一个单链表的引用结点 head。链表中每个结点的值不是 0 就是 1。已知此链表是一个整数数字的二进制表示形式。请你返回该链表所表示数字的 十进制值
链表不为空; 链表的结点总数不超过 30; 每个结点的值不是0就是 1

示例:

输入:head = [1,0,1]
输出:5
解释:二进制数 (101) 转化为十进制数 (5)

解题思路

1.建立一个数组,然后遍历链表,将链表中的值存取到数组中,将数组的内容转换成十进制,在size-1位置的反而是于二的零次方相乘,所以可以得到如下代码

	int getDecimalValue(struct ListNode* head)
 {

    int arr[31];
    int i=0;
    int flag=0;//做标记,如果数组中没有1,无论链表多长结果都是0
    while(head!=NULL)
    {
        arr[i]=head->val;
        i++;
        if(head->val==1)
        {
            flag=1;
        }
        head=head->next;
    }
    //将链表中的数值全部提取到数组中,必须要拿到数组的有效长度
    int sum=0;
    int sz=i;

    if(flag==0)
        return 0;
    else
    {
        for(i=0;i<sz;i++)
        {
           if(arr[i]!=0)
           {
                sum+=pow(2,sz-1-i);
           }
        }
    }

    return sum;
}

2.此外还可以利用位运算,第一次就从链表中拿到的那个数其实是二的size-1次方,而左移一位就有乘二的效果

int getDecimalValue(struct ListNode* head)
{
    int sum=0;
    
    while(head!=NULL)
    {
        sum=(sum<<1)+head->val;
        
        head=head->next;
    }
    
    return sum;
}

人们总是高估短期努力能带来的提升,而忽略长期坚持带来的改变。今天是第五天,也是第二十题了,你还在坚持吗?

相关文章:

  • 22 k8s常用命令
  • 接口的定义和实现
  • 蓝桥杯冲刺 - week1
  • windows微服务部署
  • 深入了解JVM:Java程序背后的核心原理
  • 【新星计划2023】SQL SERVER (01) -- 基础知识
  • 【Node.js】身份认证,Cookie和Session的认证机制,express中使用session认证和JWT认证
  • 算法基础-回溯算法
  • SpringBoot整合Flink(施耐德PLC物联网信息采集)
  • vue3 组件篇 Message
  • clip精读
  • 超级实用,解密云原生监控技术,使用prometheus轻松搞定redis监控
  • MyBatis高频面试题
  • C++中那些你不知道的未定义行为
  • 电容在微分、积分电路中的本质以及应用
  • 《Javascript数据结构和算法》笔记-「字典和散列表」
  • JWT究竟是什么呢?
  • mysql中InnoDB引擎中页的概念
  • React-flux杂记
  • 编写高质量JavaScript代码之并发
  • 分享一份非常强势的Android面试题
  • 利用jquery编写加法运算验证码
  • 自制字幕遮挡器
  • #宝哥教你#查看jquery绑定的事件函数
  • #我与Java虚拟机的故事#连载06:收获颇多的经典之作
  • #我与Java虚拟机的故事#连载08:书读百遍其义自见
  • ( )的作用是将计算机中的信息传送给用户,计算机应用基础 吉大15春学期《计算机应用基础》在线作业二及答案...
  • (2015)JS ES6 必知的十个 特性
  • (备忘)Java Map 遍历
  • (动手学习深度学习)第13章 计算机视觉---微调
  • (分类)KNN算法- 参数调优
  • (黑客游戏)HackTheGame1.21 过关攻略
  • (四)汇编语言——简单程序
  • ..回顾17,展望18
  • .mysql secret在哪_MYSQL基本操作(上)
  • .NET 6 Mysql Canal (CDC 增量同步,捕获变更数据) 案例版
  • .net 按比例显示图片的缩略图
  • .Net7 环境安装配置
  • .Net通用分页类(存储过程分页版,可以选择页码的显示样式,且有中英选择)
  • ?php echo ?,?php echo Hello world!;?
  • @SpringBootApplication 包含的三个注解及其含义
  • @test注解_Spring 自定义注解你了解过吗?
  • [ vulhub漏洞复现篇 ] Django SQL注入漏洞复现 CVE-2021-35042
  • [.NET 即时通信SignalR] 认识SignalR (一)
  • [C#]科学计数法(scientific notation)显示为正常数字
  • [C#基础知识]专题十三:全面解析对象集合初始化器、匿名类型和隐式类型
  • [C++]18:set和map的使用
  • [DM复习]Apriori算法-国会投票记录关联规则挖掘(上)
  • [Gamma]阶段测试报告
  • [HTML]Web前端开发技术28(HTML5、CSS3、JavaScript )JavaScript基础——喵喵画网页
  • [IE编程] IE 是如何决定Accept-Language 属性的
  • [ListView.View=List]的垂直滚动条
  • [NAND Flash 6.2] NAND 初始化常用命令:复位 (Reset) 和 Read ID 和 Read UID 操作和代码实现
  • [week5]每周总结与工作计划
  • [Windows]服务注册工具(nssm)