5月28日 每日leetcode三题(28/面试题63/233)

前言

刷5月16日的老题,简单题是出现次数一半的数字,因为刷过就换成leetcode第28题了。今天刷的是28.实现 strStr()、面试题63.股票的最大利润、233.数字 1 的个数。

28.实现 strStr()(容易):
题目描述:

实现 strStr() 函数。

给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回  -1。

当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。

对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/implement-strstr

题解:

官方给的常规的解法是,对所有的子串进行逐一比较,用needle长度的窗口,寻找第一个符合条件的子串。
时间复杂度为O((N-L)*L),L是needle的长度,N是haystack的长度。
我采用的官方解法里的第二个,双指针法。优点是不需要对每个子串进行比较,只有当子串的第一位跟needle字符串的第一位相等是,才会开始比较。最优情况O(N),最坏情况O((N-L)*L),会更省时间。

看到讨论区里面各种KMP,有点没看懂,感觉双指针法应该是挺快的解法了,如果有更快更好理解的算法,还希望有大佬评论指点哈哈。

Code
var strStr = function(haystack, needle) {
    if(needle=="") return 0;
    if(needle.length>haystack.length) return -1;
    for(let i=0;i<=haystack.length-needle.length;i++){
        let index=0;
        if(haystack[i]==needle[index]){
            index++;
            for(let j=i+1;j-i<needle.length;j++){
                if(haystack[j]==needle[index]){
                    index++;
                }else{
                    index=0;
                }
            }
            if(index==needle.length)
                return i;
            else if(index==0)
                continue;
        }else
            continue;
    }
    return -1;
};
面试题63.股票的最大利润(中等):
题目描述:

假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖该股票一次可能获得的最大利润是多少?

示例 1:
输入: [7,1,5,3,6,4]
输出: 5
解释:
在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。

示例 2:
输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。

限制:

0 <= 数组长度 <= 10^5

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/gu-piao-de-zui-da-li-run-lcof

题解:

看到这道题还以为是动态规划,不过仔细想想其实就是寻找一个买入点和卖出点之差足够大的序列。可以从头遍历,记录一个较小数的下标,然后向右搜索:如果是遇到比较小数大的数字,就更新卖出价格。遇到比较小数更小的数字,就更新较小数的下标。
时间复杂度为O(n)。

Code
//第一次AC(95%,100%)
var maxProfit = function(prices) {
    if(prices.length==1) return 0;
    let pre=0;
    let max=0;
    for(let i=1;i<prices.length;i++){
        if(prices[i]>prices[pre])
            max=Math.max(max,prices[i]-prices[pre]);
        else{
            pre=i;
        }
    }
    return max;
};
233.数字 1 的个数(困难):
题目描述:

给定一个整数 n,计算所有小于等于 n 的非负整数中数字 1 出现的个数。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/number-of-digit-one/solution/shu-zi-1-de-ge-shu-by-leetcode

题解:

数学归纳,每个位及它的后一位上(比如说个位和十位),1的个数可以用公式
( n / ( i ∗ 10 ) ) ∗ i + min ⁡ ( max ⁡ ( ( n mod (i*10) ) − i + 1 , 0 ) , i ) (n/(i*10))*i+{\min(\max((\text{n mod (i*10)} )-i+1,0),i)} (n/(i10))i+min(max((n mod (i*10))i+1,0),i) 来表示。

Code
var countDigitOne = function(n) {
    let count=0;
    for(let i=1;i<=n;i*=10){
        let divide=i*10;
        count+=Math.floor(n/divide)*i+Math.min(Math.max(n%divide-i+1,0),i);
    }
    return count;
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值