每日算法-250408

记录今天解决的两道 LeetCode 算法题,主要涉及二分查找的应用。


1283. 使结果不超过阈值的最小除数

题目描述

Problem Description for 1283

思路

核心思路是 二分查找

解题过程

  1. 为什么可以使用二分?
    关键在于单调性。对于一个固定的数组 nums,当除数 divisor 增大时,每个元素 num / divisor (向上取整) 的值是 非递增 的,因此它们的总和也是 非递增 的。
    我们要求的是满足 sum <= threshold最小 divisor

    • 如果当前除数 mid 计算出的总和 sum 大于 threshold,说明 mid 太小了,我们需要增大除数。因此,真正的答案一定在 [mid + 1, right] 区间。
    • 如果当前除数 mid 计算出的总和 sum 小于等于 threshold,说明 mid 是一个可能的解,但可能存在更小的除数也满足条件。因此,我们尝试在 [left, mid - 1] 区间寻找更小的解,同时记录 mid 作为潜在答案。
  2. 二分查找的目标?
    我们要查找的是满足条件的 最小 正整数除数。

  3. 查找范围?

    • left:最小可能的除数是 1(题目要求正整数除数)。
    • right:最大可能的除数是多少?如果除数非常大(例如,等于数组中的最大元素),那么每个数除后的结果向上取整至少是 1,总和至少是 nums.length。如果除数是数组中的最大值 max(nums),那么每个 ceil(num / max(nums)) 都是 1,总和为 nums.length。因此,一个合理的上界是数组中的最大元素值。如果阈值 threshold 非常小(比如等于 nums.length),那么除数可能需要等于最大元素值。
  4. check 函数
    需要一个辅助函数 check(nums, divisor) 来计算在当前除数 divisor 下,数组元素的除法结果(向上取整)之和。计算 ceil(x / divisor) 可以用 (x + divisor - 1) / divisor 的整数除法实现,或者像原始代码那样判断余数。

复杂度

  • 时间复杂度: O(N log M)
    • 其中 N 是数组 nums 的长度。
    • M 是二分查找的范围上限,即 nums 中的最大元素值。
    • 每次 check 函数需要 O(N) 的时间遍历数组。
    • 二分查找需要 O(log M) 次 check 调用。
  • 空间复杂度: O(1)
    • 我们只需要常数级别的额外空间来存储 left, right, midsum 等变量。

Code

class Solution {public int smallestDivisor(int[] nums, int threshold) {Arrays.sort(nums);int left = 1, right = nums[nums.length - 1];while (left <= right) {int mid = left + (right - left) / 2;if (check(nums, mid) < threshold + 1) {right = mid - 1;} else {left = mid + 1;}}return left;}private int check(int[] nums, int divisor) {int sum = 0;for (int x : nums) {if (x % divisor == 0) {sum += x / divisor;} else {sum += x / divisor + 1;}}return sum;}
}

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

题目描述

Problem Description for 1170

思路

结合 预处理二分查找

解题过程

  1. 计算频率 f(s)
    首先,需要实现一个函数 f(s),用于计算给定字符串 s 中字典序最小的字符的出现次数。遍历字符串,找到最小字符,并统计其出现次数。

  2. 预处理 words
    words 数组中的每个字符串 W,计算其 f(W),并将这些频率值存储在一个新的整数数组 wFreq 中。

  3. 排序 wFreq
    为了能够高效地查找满足 f(queries[i]) < f(W)W 的数量,我们将 wFreq 数组进行升序排序。

  4. 二分查找
    对于每个 queries[i]:
    a. 计算 qVal = f(queries[i])
    b. 我们需要在已排序的 wFreq 数组中找到 第一个 大于 qVal 的元素的位置 idx
    c. wFreq 数组中从 idx 到末尾的所有元素都满足 f(W) > qVal。因此,满足条件的 W 的数量就是 wFreq.length - idx
    d. 查找 “第一个大于 qVal 的元素” 可以通过二分查找实现。具体地,我们可以查找 第一个大于等于 qVal + 1 的元素的位置。

复杂度

  • 时间复杂度: O(Lq * N + Lw * M + M log M + N log M)
    • 其中 N 是 queries 的长度,M 是 words 的长度。
    • Lq 和 Lw 分别是 querieswords 中字符串的最大长度。
    • 计算所有 f(queries[i]) 需要 O(Lq * N)。
    • 计算所有 f(W) 需要 O(Lw * M)。
    • wFreq 排序需要 O(M log M)。
    • 对每个 query 进行二分查找需要 O(log M),总共 N 次查找为 O(N log M)。
    • 整体复杂度由这些部分相加决定。如果字符串长度较小,主要由排序和查找决定。
  • 空间复杂度: O(N + M)
    • 需要 O(N) 空间存储 queries 的频率结果(或者直接在结果数组中计算)。
    • 需要 O(M) 空间存储 words 的频率数组 wFreq
    • 排序可能需要 O(log M) 或 O(M) 的额外栈空间或临时空间,但 O(N+M) 通常是主导。

Code

import java.util.Arrays;class Solution {public int[] numSmallerByFrequency(String[] queries, String[] words) {int n = queries.length, m = words.length;int[] qFreq = new int[n]; // 存储 queries 的 f 值int[] wFreq = new int[m]; // 存储 words 的 f 值int[] ans = new int[n];   // 存储最终结果// 1. 计算 queries 中每个字符串的 f 值for (int i = 0; i < n; i++) {qFreq[i] = calculateF(queries[i]);}// 2. 计算 words 中每个字符串的 f 值for (int i = 0; i < m; i++) {wFreq[i] = calculateF(words[i]);}// 3. 对 words 的频率数组进行排序Arrays.sort(wFreq);// 4. 对每个 query 的频率值,在排好序的 wFreq 中进行二分查找for (int i = 0; i < n; i++) {int targetFreq = qFreq[i];// 查找第一个严格大于 targetFreq 的元素的位置// 等价于查找第一个大于等于 targetFreq + 1 的元素的位置int index = findFirstGreater(wFreq, targetFreq);ans[i] = m - index; // 从该位置到数组末尾的元素个数即为所求}return ans;}// 计算字符串 s 的 f(s) 值private int calculateF(String s) {if (s == null || s.isEmpty()) {return 0;}char minChar = 'z' + 1; // 初始化为一个比 'z' 大的字符int count = 0;for (char c : s.toCharArray()) {if (c < minChar) {minChar = c;count = 1; // 找到了更小的字符,重置计数} else if (c == minChar) {count++; // 遇到了相同的最小字符,增加计数}}return count;}// 在升序数组 arr 中查找第一个严格大于 target 的元素的索引// 如果所有元素都小于等于 target,返回 arr.lengthprivate int findFirstGreater(int[] arr, int target) {int left = 0, right = arr.length - 1;int resultIndex = arr.length; // 默认为数组长度,表示没找到while (left <= right) {int mid = left + (right - left) / 2;if (arr[mid] > target) {// arr[mid] 比 target 大,可能是第一个,也可能前面还有resultIndex = mid; // 记录当前这个可能的位置right = mid - 1;  // 继续向左查找更小的索引} else {// arr[mid] 小于等于 target,需要向右查找更大的值left = mid + 1;}}return resultIndex;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/75115.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL的子查询

一、前言 MySQL 子查询是指嵌套在其他 SQL 语句&#xff08;如 SELECT、WHERE、FROM 等&#xff09;内部的查询。用于辅助主查询完成复杂的数据筛选或计算。 二、子查询分类 标量子查询 描述&#xff1a;返回 单行单列&#xff08;一个值&#xff09;&#xff0c;常用于比较运…

Linux 基础入门操作 前言 VIM的基本操作 2

1 VIM的背景介绍 Vi 的诞生与1976年&#xff0c;Vim 的前身是 Vi&#xff08;Visual Editor&#xff09;&#xff0c;由 Bill Joy 在 BSD Unix 系统上开发&#xff0c;作为 ed&#xff08;行编辑器&#xff09;的改进版本&#xff0c;提供全屏编辑功能&#xff0c;成为 Unix/L…

Java:Set操作

目录 Set 转 List Set 转 List Set<String>set new HashSet<String>(); set.add("c"); set.add("d"); set.add("a"); set.add("a");//方法一&#xff1a; List<String>list new ArrayList<String>(set);//…

算力驱动未来:从边缘计算到高阶AI的算力革命

算力驱动未来&#xff1a;从边缘计算到高阶AI的算力革命 摘要 本文深入探讨了不同算力水平&#xff08;20TOPS至160TOPS&#xff09;在人工智能领域的多样化应用场景。从边缘计算的实时目标检测到自动驾驶的多传感器融合&#xff0c;从自然语言处理的大模型应用到AI for Scie…

虚拟机上安装openEuler和openGauss数据库

1.虚拟机版本选择VM 16 PRO 2.openEuler版本选择openEuler-22.03-LTS-SP4-x86_64 下载地址&#xff1a;https://mirrors.aliyun.com/openeuler/openEuler-22.03-LTS-SP4/ISO/x86_64/openEuler-22.03-LTS-SP4-x86_64-dvd.iso 3.虚拟机安装openEuler过程&#xff1a; 4.安装ope…

0_Pytorch中的张量操作

[引言]张量的概念 1.基本概念 张量是一个通用的多维数组&#xff0c;可以表示标量&#xff08;0 维&#xff09;、向量&#xff08;1 维&#xff09;、矩阵&#xff08;2 维&#xff09;以及更高维度的数据。张量是 PyTorch 中的核心数据结构&#xff0c;用于表示和操作数据。…

LS-LINUX-002 简易创建SSH

LS-LINUX-002 简易创建SSH 1. CentOS 8 创建和配置SSH服务 1.1 安装SSH服务 CentOS 8 默认已经安装了OpenSSH服务。如果没有安装&#xff0c;可以使用以下命令安装&#xff1a; sudo dnf install -y openssh-server1.2 启动SSH服务 安装完成后&#xff0c;需要启动SSH服务…

计算机专业求职面试的常见题目分类整理

以下是计算机专业求职面试的常见题目分类整理&#xff0c;每个大类精选20道高频问题&#xff0c;结合参考内容进行解析与扩展&#xff0c;帮助系统化备考&#xff1a; 一、数据结构与算法 解释时间复杂度和空间复杂度 时间复杂度衡量算法执行时间随输入规模的增长趋势&#xf…

脚本启动 Java 程序

如果你想在后台启动一个 Java 程序&#xff0c;并在终端窗口中显示一个自定义的名字&#xff0c;可以通过编写一个简单的脚本来实现。以下是一个基于 Linux/macOS 的解决方案&#xff0c;使用 Bash 脚本启动 Java 程序&#xff0c;并在终端窗口中显示自定义标题。 示例脚本 创建…

CentOS禁用nouveau驱动

1、验证 nouveau 是否在运行 lsmod | grep nouveau如果命令返回结果&#xff0c;说明 nouveau 驱动正在运行。 2、编辑黑名单文件 通过编辑黑名单配置文件来禁用 nouveau 驱动&#xff0c;这样在系统启动时不会加载它。 vi /etc/modprobe.d/blacklist-nouveau.conf修改以下…

Linux: network: tcpdump: packets dropped by kernel

文章目录 最近遇到一个问题原因libpcap/tcpdump 接口linux/libpcap 接口内核的处理原因可能有以下几种:解决方法:man pcap_stats最近遇到一个问题 tcpdump命令显示有dropped的包,而且是被内核drop的。 [root@-one-01 ~]# tcpdump -i any udp and port 8080 -v -w /root/udp…

WEB安全--提权思路

一、情形 在我们成功上传webshell到服务器中并拿到权限时&#xff0c;发现我们的权限很低无法执行特定的命令&#xff0c;这时为了能做更多的操作&#xff0c;我们就需要提升权限。 二、方式 2.1、Windows提权 1、普通用户执行systeminfo命令获取服务器的基本信息&#xff0…

001 vue

https://cn.vuejs.org/ 文章目录 v-bindv-modelv-on修饰符条件渲染/控制&#xff1a;v-if v-show列表渲染 M&#xff1a;即Model&#xff0c;模型&#xff0c;包括数据和一些基本操作 V&#xff1a;即View&#xff0c;视图&#xff0c;页面渲染结果 VM&#xff1a;即View-Mode…

Tomcat 负载均衡

目录 二、Tomcat Web Server 2.1 Tomcat 部署 2.1.1 Tomcat 介绍 2.1.2 Tomcat 安装 2.2 Tomcat 服务管理 2.2.1 Tomcat 启停 2.2.2 目录说明 2.2.3编辑主页 2.3 Tomcat管理控制台 2.3.1开启远程管理 2.3.2 配置远程管理密码 三、负载均衡 3.1 重新编译Nginx 3.1.1 确…

使用SpringSecurity下,发生重定向异常

使用SpringSecurity下&#xff0c;发生空转异常 环境信息&#xff1a; Spring Boot 3.4.4 &#xff0c; jdk 17 &#xff0c; springSecurity 6.4.4 问题背景&#xff1a; 没有自定义controller &#xff0c;改写了login 页面&#xff0c;并且进行了成功后的跳转处理&#xf…

S130N-ISI 全栈方案与云平台深度协同:重构 PLC 开发新范式

一、什么是 PLC&#xff1f; 1.技术定义 PLC&#xff08;Power Line Communication&#xff09;是一种创新的通信技术&#xff0c;它以电力线作为天然的传输介质&#xff0c;通过先进的信号调制技术将高频数据信号叠加于工频电流之上&#xff0c;实现电力输送与数据通信的双频共…

SU-YOLO:基于脉冲神经网络的高效水下目标检测模型解析

论文地址:https://arxiv.org/pdf/2503.24389 目录 一、论文概述 二、创新点解析 1. 基于脉冲的水下图像去噪(SpikeDenoiser) 原理与结构 2. 分离批归一化(SeBN) 原理与结构 3. 优化的残差块(SU-Block) 原理与结构 三、代码复现指南 环境配置 模型训练 四、…

实现阿里云服务器上的文字聊天程序以及C语言写的进程间通信(IPC)程序

实现阿里云服务器上的文字聊天程序以及C语言写的进程间通信&#xff08;IPC&#xff09;程序 1. 基于 Linux 中的管道进行进程间通信 我们首先使用管道进行进程间通信&#xff0c;这对于简单的聊天程序来说是一个比较简单且实用的方法。 步骤&#xff1a; 创建管道&#xf…

COMSOL 与人工智能融合的多物理场应用:28个案例的思路、方法与工具概述

应用案例概述 基于 COMSOL 与人工智能&#xff08;AI&#xff09;结合的应用案例涵盖了 28 个多领域场景&#xff0c;包括工程&#xff08;如热传导优化、结构力学预测&#xff09;、能源&#xff08;如电池热管理、燃料电池性能&#xff09;、生物医学&#xff08;如药物传递…

SAN及其ZONE

目录 一、什么是SAN? 二、什么是ZONE? 三、配置ZONE 2.1 核心概念 2.2 划分原则 2.3 Zone划分最佳实践 2.4 配置语法 1). 基于端口&#xff08;Domain,Port&#xff09;的zone语法 2). 基于WWN&#xff08;World Wide Name&#xff09;的Zone语法 3). 使用Alias简化配置 4).…