leetcode每日一题

2023.1.1 2351.第一个出现的字母:

给你一个由小写英文字母组成的字符串 s ,请你找出并返回第一个出现两次的字母
注意:
  • 如果 a 的第二次出现比b的第二次出现在字符串中的位置更靠前,则认为字母a在字母b之前出现两次
  • s包含至少一个出现两次的字母
  • 示例:输入:s=“abcdd”
  • 输出:“d”
//哈希表
char repeatedCharacter(char * s){
    int hash[26] = {0};//数组哈希表
    for (int i = 0; i < strlen(s); ++i) {//枚举字符串每一个字符
        if (++hash[s[i] - 'a'] >= 2) {//记录出现次数
            return s[i];
        }
    }
    return -1;
}
//哈希表
char repeatedCharacter(char * s) {
    int seen[26];
    memset(seen, 0, sizeof(seen));
    for (int i = 0; s[i] != '\0'; i++) {
        if (seen[s[i] - 'a'] > 0) {
            return s[i];
        }
        seen[s[i] - 'a'] = 1;
    }
    return ' ';
}

2023.1.2 1801.积压订单中的订单总数:

在这里插入图片描述
在这里插入图片描述

class Solution:
    def getNumberOfBacklogOrders(self, orders: List[List[int]]) -> int:

        buybacklog = []
        sellbacklog = []
        MOD = 10 ** 9 + 7
        n = len(orders)
        for i in range(n):#遍历输入的订单
            if orders[i][2] == 0:#采购订单
                while orders[i][1] and sellbacklog and sellbacklog[0][0] <= orders[i][0]:
                	#当采购订单数量不为0,小堆栈中销售订单最低价格小于采购订单价格时
                    if sellbacklog[0][1] > orders[i][1]:#如果销售订单数量大于采购订单数量
                        sellbacklog[0][1] -= orders[i][1]#用销售订单数减去采购订单数
                        orders[i][1] = 0#采购订单数归0
                        break
                    orders[i][1] -= sellbacklog[0][1]
                    #如果销售订单数量小于等于采购订单数量,用采购订单数减去销售订单数
                    heapq.heappop(sellbacklog)#将销售订单最低价格的订单弹出
                if orders[i][1]:#如果采购订单数大于0
                    heapq.heappush(buybacklog, [-orders[i][0], orders[i][1]])
                    #将采购订单推入大堆栈,则此时价格应取负

            elif orders[i][2] == 1:
                while orders[i][1] and buybacklog and -buybacklog[0][0] >= orders[i][0]:
                #大堆栈中价格取负
                    if buybacklog[0][1] > orders[i][1]:
                        buybacklog[0][1] -= orders[i][1]
                        orders[i][1] = 0
                        break
                    orders[i][1] -= buybacklog[0][1]
                    heapq.heappop(buybacklog)
                if orders[i][1]:
                    heapq.heappush(sellbacklog, [orders[i][0], orders[i][1]])
                    #销售订单推入小堆栈不用取负

        return (sum(x for _, x in buybacklog) + sum(x for _, x in sellbacklog)) % MOD

2023.1.3 2042.检查句子中的数字是否递增

在这里插入图片描述
在这里插入图片描述

//模拟
bool areNumbersAscending(char * s) {
    int pre = 0, pos = 0;//pre记录前一个整数
    while (s[pos] != '\0') {
        if (isdigit(s[pos])) {
            int cur = 0;
            while (s[pos] != '\0' && isdigit(s[pos])) {
            //由于每个token要么是由0-9组成的正整数要么是字母,当该整数为两位数及以上时就需要把前一个数字先乘10再加下一位数字
                cur = cur * 10 + s[pos] - '0';//将字符转换为十进制整数
                pos++;
            }
            if (cur <= pre) {//如果该整数小于记录的前一个整数
                return false;
            }
            pre = cur;//否则把该整数赋值给pre
        } else {
            pos++;//如果不是整数
        }
    }
    return true;
}

2023.1.4 1802.有界数组中指定下标处的最大值

在这里插入图片描述

思路:

最值问题考虑贪心算法,指定下标处要最大化,则可以通过二分法找出符合条件的有效元素值,根据贪心算法,该值要符合的条件是,从该值向左向右递减且保证相差的绝对值都是1,且最终数组元素和不大于maxsum

  • 向左向右递减有两种情况:
  • 1.如果指定下标index位置处到边界的距离length大于等于选取的有效元素值x,那么会出现x递减之后会出现减到0的情况,那么对于距离大于x的位置,就放置最小值1
  • 2.index位置到边界的距离小于x,递减即可
  • 第二种情况以 5为有效元素值为例 从5到最后边界:5 4 3 2 ,big=5,length=3,有length+1<big的规律,减到边界值small为big-length=2,有等差数列求和返回左边或右边的数组元素和(不包括有效元素值)
  • 第一种情况以5 4 3 2 1 1 1为例,big=5,length=6,有length+1>(=)big的规律,big递减到1后面值全为1,后面的值的和为ones=length-(big-1)=2,同样进行等差求和(不包括有效元素值)
long cal(int big,int length){//big为指定下标处元素的最大值,length为到边界的距离
	if(length + 1 < big){//如果是第二种情况
		int small = big - length;
		return (long) (big - 1 + small) *length /2;//等差数列求和
	}
	else {//第一种情况
		int ones = length - (big - 1);
		return (long) big * (big - 1) / 2 +ones;
	}
}

boll valid(int mind,int n,int index,int maxsum){//判断选择的值是否有效
	int left = index;
	int right = n- index - 1;
	//数组元素和=当前位置值+左边和+右边和
	return (mid + cal(mid,left)+cal(mid,right)) <=maxsum;
}

int maxvalue(int n,int index,int maxsum){//二分法选择元素值
	int left = 1,right = maxsum;//选择的值一定在1和maxsum之间
	while(left < right){//多次选值,选出最大化的值
		int mid = (left + right + 1) / 2;//向上取整
		if(valid(mid,n,index,maxsum)){//进行判断,如果有效
			left = mid;//将left赋值为该值,由于最后返回的是left,所以不用加1
		}else{//如果无效
			right = mid - 1//将right赋值为该值-1,从该值的左侧第一个值开始
		}
	}
	return left;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值