练习题(2024/5/12)

1二分查找

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1


示例 1:

输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4

示例 2:

输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1

提示:

  1. 你可以假设 nums 中的所有元素是不重复的。
  2. n 将在 [1, 10000]之间。
  3. nums 的每个元素都将在 [-9999, 9999]之间。

思路:

  1. 确定初始搜索区间:将左边界 left 设置为数组起始索引,右边界 right 设置为数组末尾索引。
  2. 使用循环进行搜索:只要左边界 left 小于或等于右边界 right,就继续搜索。这是因为当左边界和右边界相等时,区间仍然有效,可能存在目标值。
  3. 计算中间索引:通过 left + ((right - left) / 2) 来计算中间索引,这样做是为了防止整数溢出,与直接使用 (left + right) / 2 相比更安全。
  4. 比较中间值和目标值:将中间索引对应的值与目标值进行比较。
  5. 根据比较结果更新搜索区间:
    • 如果中间值大于目标值,则目标值在左侧,更新右边界为 middle - 1
    • 如果中间值小于目标值,则目标值在右侧,更新左边界为 middle + 1
    • 如果中间值等于目标值,则找到目标值,直接返回中间索引。
  6. 若循环结束仍未找到目标值,则返回 -1,表示目标值不存在于数组中。

代码:

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0;
        int right = nums.size() - 1; // 定义target在左闭右闭的区间里,[left, right]
        while (left <= right) { // 当left==right,区间[left, right]依然有效,所以用 <=
            int middle = left + ((right - left) / 2);// 防止溢出 等同于(left + right)/2
            if (nums[middle] > target) {
                right = middle - 1; // target 在左区间,所以[left, middle - 1]
            } else if (nums[middle] < target) {
                left = middle + 1; // target 在右区间,所以[middle + 1, right]
            } else { // nums[middle] == target
                return middle; // 数组中找到目标值,直接返回下标
            }
        }
        // 未找到目标值
        return -1;
    }
};

2反转字符串 II

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

示例 1:

输入:s = ["h","e","l","l","o"]
输出:["o","l","l","e","h"]

示例 2:

输入:s = ["H","a","n","n","a","h"]
输出:["h","a","n","n","a","H"]

提示:

  • 1 <= s.length <= 105
  • s[i] 都是 ASCII 码表中的可打印字符

思路:

  1. 使用循环遍历字符串,每次步长为 2k,以便处理每个分段。
  2. 对于每个分段:
    • 如果剩余字串长度大于等于 k,则反转前 k 个字符。
    • 如果剩余字串长度小于 k,则反转剩余所有字符。
  3. 将反转后的字符串返回。

代码:

class Solution {
public:
    string reverseStr(string s, int k) {
        for(int i=0;i<s.size();i+=2*k){ // 每次移动步长为 2k
            if(i+k<=s.size()){ // 如果剩余字串长度大于等于 k,则反转前 k 个字符
                reverse(s.begin()+i,s.begin()+i+k);
            }else{ // 如果剩余字串长度小于 k,则反转剩余所有字符
                reverse(s.begin()+i,s.end());
            }
        }
        return s;
    }
};

3替换数字(第八期模拟笔试)

给定一个字符串 s,它包含小写字母和数字字符,请编写一个函数,将字符串中的字母字符保持不变,而将每个数字字符替换为number。

例如,对于输入字符串 "a1b2c3",函数应该将其转换为 "anumberbnumbercnumber"。

对于输入字符串 "a5b",函数应该将其转换为 "anumberb"

输入:一个字符串 s,s 仅包含小写字母和数字字符。

输出:打印一个新的字符串,其中每个数字字符都被替换为了number

样例输入:a1b2c3

样例输出:anumberbnumbercnumber

数据范围:1 <= s.length < 10000。

思路:

解题思路主要集中在字符串的遍历和替换过程:

  1. 遍历字符串并统计数字个数: 使用一个循环遍历输入的字符串,每当遇到一个数字字符,就将计数器 count 加一。

  2. 扩充字符串大小: 统计完数字个数后,需要将字符串的大小扩充,以便容纳替换后的 “number”。由于每个数字都会替换成 “number”,所以字符串大小需要增加 count * 5

  3. 从后往前替换数字为 “number”: 从原始字符串的末尾开始向前遍历,如果遇到数字字符,则依次将 “number” 替换进去;如果遇到非数字字符,则直接复制到新字符串中。这里需要维护好原始字符串和新字符串的索引关系,确保替换操作正确进行。

  4. 输出替换后的字符串: 完成替换后,输出新的字符串即可。

代码:

#include <iostream>
using namespace std;

int main() {
    string s; // 定义字符串变量
    while (cin >> s) { // 循环读取输入的字符串
        int sOldIndex = s.size() - 1; // 记录原始字符串最后一个字符的索引
        int count = 0; // 统计数字的个数
        for (int i = 0; i < s.size(); i++) { // 遍历字符串
            if (s[i] >= '0' && s[i] <= '9') { // 如果当前字符是数字
                count++; // 数字个数加一
            }
        }
        // 扩充字符串 s 的大小,也就是将每个数字替换成 "number" 之后的大小
        s.resize(s.size() + count * 5);
        int sNewIndex = s.size() - 1; // 新字符串的最后一个字符的索引
        // 从后往前将数字替换为 "number"
        while (sOldIndex >= 0) { // 从原始字符串的末尾开始遍历
            if (s[sOldIndex] >= '0' && s[sOldIndex] <= '9') { // 如果当前字符是数字
                s[sNewIndex--] = 'r'; // 替换为 'r'
                s[sNewIndex--] = 'e'; // 替换为 'e'
                s[sNewIndex--] = 'b'; // 替换为 'b'
                s[sNewIndex--] = 'm'; // 替换为 'm'
                s[sNewIndex--] = 'u'; // 替换为 'u'
                s[sNewIndex--] = 'n'; // 替换为 'n'
            } else { // 如果当前字符不是数字
                s[sNewIndex--] = s[sOldIndex]; // 不变,直接复制
            }
            sOldIndex--; // 原始字符串索引向前移动
        }
        cout << s << endl; // 输出替换后的字符串       
    }
}

4反转链表

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

示例 1:

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

示例 2:

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

示例 3:

输入:head = []
输出:[]

提示:

  • 链表中节点的数目范围是 [0, 5000]
  • -5000 <= Node.val <= 5000

思路:

cur 和 pre 两个指针构成了双指针的思路,用来实现链表的反转。

  • cur 指针是当前遍历到的节点,初始时指向头节点 head
  • pre 指针是 cur 的前一个节点,在循环中起到了记录已经反转部分的作用。

每次循环中的操作主要包括:

  1. 将 temp 指针指向 cur 的下一个节点,以便在修改 cur->next 后能找到下一个节点。
  2. 将 cur->next 指向 pre,实现当前节点的反转。
  3. 更新 pre 和 cur 指针,将 pre 移向 cur 的位置,将 cur 移向 temp 的位置

代码:

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* temp; // 保存cur的下一个节点
        ListNode* cur = head;
        ListNode* pre = NULL;
        while(cur) {
            temp = cur->next;  // 保存一下 cur的下一个节点,因为接下来要改变cur->next
            cur->next = pre; // 翻转操作
            // 更新pre 和 cur指针
            pre = cur;
            cur = temp;
        }
        return pre;
    }
};

5求关注者的数量

表: Followers

+-------------+------+
| Column Name | Type |
+-------------+------+
| user_id     | int  |
| follower_id | int  |
+-------------+------+
(user_id, follower_id) 是这个表的主键(具有唯一值的列的组合)。
该表包含一个关注关系中关注者和用户的编号,其中关注者关注用户。

编写解决方案,对于每一个用户,返回该用户的关注者数量。

按 user_id 的顺序返回结果表。

查询结果的格式如下示例所示。

示例 1:

输入:
Followers 表:
+---------+-------------+
| user_id | follower_id |
+---------+-------------+
| 0       | 1           |
| 1       | 0           |
| 2       | 0           |
| 2       | 1           |
+---------+-------------+
输出:
+---------+----------------+
| user_id | followers_count|
+---------+----------------+
| 0       | 1              |
| 1       | 1              |
| 2       | 2              |
+---------+----------------+
解释:
0 的关注者有 {1}
1 的关注者有 {0}
2 的关注者有 {0,1}

代码:

select user_id,count(follower_id) followers_count
from Followers 
group by user_id
order by user_id asc;

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

异常处理/ROS2异常处理模块源码解读与浅析

文章目录 概述ros2/rcutils/src/error_handling模块自身异常处理错误状态结构与存储本模块初始化错误状态的设置错误状态的获取错误状态的清理不丢失旧错误状态把手段还原为目的其他 概述 本文从如下几个方面对 ROS2.0 中 rcutils 库 error_handling 错误处理模块的源码进行解…

day-34 二叉树的锯齿形层序遍历

思路 相较于二叉树的层序遍历&#xff0c;多了一个flag变量,当flag等于0时&#xff0c;把当前层的数组从左到右放入链表&#xff0c;当flag等于1时&#xff0c;把当前层的数组从右到左放入链表。 解题方法 注意&#xff1a;链表删除一个数据后会立即重排&#xff0c;所以删除同…

Linux进程控制——Linux进程终止

前言&#xff1a;前面了解完前面的Linux进程基础概念后&#xff0c;我们算是解决了Linux进程中的一大麻烦&#xff0c;现在我们准备更深入的了解Linux进程——Linux进程控制&#xff01; 我们主要介绍的Linux进程控制内容包括&#xff1a;进程终止&#xff0c;进程等待与替换&a…

GoF之代理模式(静态代理+动态代理(JDK动态代理+CGLIB动态代理带有一步一步详细步骤))

1. GoF之代理模式&#xff08;静态代理动态代理(JDK动态代理CGLIB动态代理带有一步一步详细步骤)&#xff09; 文章目录 1. GoF之代理模式&#xff08;静态代理动态代理(JDK动态代理CGLIB动态代理带有一步一步详细步骤)&#xff09;每博一文案2. 代理模式的理解3. 静态代理4. 动…

函数式接口-闭包与柯里化

闭包 定义 示例 注意 这个外部变量 x 必须是effective final 你可以生命他是final&#xff0c;你不声明也会默认他是final的&#xff0c;并且具有final的特性&#xff0c;不可变一旦x可变&#xff0c;他就不是final&#xff0c;就无法形成闭包&#xff0c;也无法与函数对象一…

单链表经典算法OJ题---力扣206,876(带图详解

1.链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09;【点击即可跳转】 思路&#xff1a;创建三个指针&#xff0c;看下图 注意&#xff1a;n3如果为空&#xff0c;则不能继续指向下一节点&#xff0c;需要进行判断 代码实现&#xff1a; struct ListNode* reverseLi…

手游掘金最新玩法,单条视频变现1w+,一部手机即可操作,保姆级教程

如果你也想通过手机赚钱&#xff0c;在这里有一个非常好的项目&#xff0c;它可以让你轻松赚到额外的收入。 这个手游掘金最新玩法&#xff0c;是一个非常受欢迎的项目&#xff0c;它可以让你通过制作单条视频来获得高额收益。不同于传统的游戏赚钱方式&#xff0c;这个方法不…

树莓派安装opencv

安装opencv 上述步骤完成后&#xff0c;输入以下代码(基于python3) sudo apt-get install python3-opencv -y不行的话&#xff0c;试试换源&#xff0c;然后 sudo apt-get update成功&#xff01; 测试opencv是否安装成功 输入 python3 然后再输入 import cv2 没有报错就…

闲来装个虚拟机Ubuntu24.04和硬盘分区及挂载

简述 最近ubuntu出新版本了&#xff0c;ubuntu24.04&#xff0c; 俗称高贵食蚁兽。5年前进行Android或者linux开发基本是在windows下的虚拟机中进行。目前&#xff0c;虽然物质基础提高了&#xff0c;功能有独立进行编译、代码管理的服务器了。可以通过ssh登录&#xff0c;但是…

[Bug]:由于中国防火墙,无法连接 huggingface.co

问题描述 : OSError: We couldnt connect to https://huggingface.co to load this file, couldnt find it in the cached files and it looks like youscan/ukr-roberta-base is not the path to a directory containing a file named config. Json. Checkout your internet …

【数据结构】排序(一)—— 希尔排序(思路演进版)

目录 一、常见的排序算法分类 二、常见排序算法的实现 2.1插入排序 2.1.1基本思想 2.1.2直接插入排序 思路 step1.单趟控制 step2.总体控制 代码实现 测试 特性总结 2.1.3 希尔排序( 缩小增量排序 ) 基本思想 思路演进 &#x1f308;1.代码实现单组排序&#…

GD32用ST-Link出现internal command error的原因及解决方法

一、GD32 F407烧录时出现can not reset target shutting down debug session 搜寻网上资料&#xff0c;发现解决方式多种多样&#xff0c;做一个简单的总结&#xff1a; 1.工程路径包含中文名 2.需更改debug选项 3.引脚冲突 4.杜邦线太长 而先前我的工程路径包含中文名也仍…

Java Array 数组

文章目录 Java Array 数组一&#xff0c;数组的介绍1. 数组的理解(Array)2. 数组相关的概念3. 数组的特点:4. 变量按照数据类型的分类5. 数组的分类6. 一维数组的使用(6个基本点)7. 数组元素的默认初始化值的情况 二&#xff0c;一维数组1. 一维数组功能测试2. 一维数组案例(1)…

香港虚拟主机哪里可以试用?用于企业建站的

香港虚拟主机适合个人、企业建站&#xff0c;包括外贸企业网站、个人博客网站、中小企业官网等&#xff0c;那么作为新手不知道哪家香港虚拟主机好用的时候&#xff0c;该如何找到可以试用的香港虚拟主机呢&#xff1f; 香港虚拟主机也称作香港空间、香港虚拟空间&#xff0c;…

深入探索Android应用数据共享之ContentProvider

本文将深入探讨Android开发中非常重要的数据共享机制 - ContentProvider。 主要内容包括: ContentProvider的基本定义及特点如何实现一个自定义的ContentProviderContentProvider对外提供的功能以及对外部应用的权限控制对ContentProvider的一些常见使用场景使用ContentProvi…

linux_用户与组

用户与组 基于账号的访问控制 账号类型&#xff1a;用户账号(UID) 、组账号(GID) 用户账号简介 作用: 1.可以登陆操作系统 2.不同的用户具备不同的权限 唯一标识&#xff1a;UID&#xff08;编号从0开始的编号&#xff0c;默认最大60000&#xff09; 管理员root的UID&…

简单贪吃蛇的实现

贪吃蛇的实现是再windows控制台上实现的&#xff0c;需要win32 API的知识 Win32 API-CSDN博客https://blog.csdn.net/bkmoo/article/details/138698452?spm1001.2014.3001.5501 游戏说明 ●地图的构建 ●蛇身的移动&#xff08;使用↑ . ↓ . ← . → 分别控制蛇的移动&am…

哈希(构造哈希函数)

哈希 哈希也可以叫散列 画一个哈希表 哈希冲突越多&#xff0c;哈希表效率越低。 闭散列开放定址法: 1.线性探测&#xff0c;依次往后去找下一个空位置。 2.二次探测&#xff0c;按2次方往后找空位置。 #pragma once #include<vector> #include<iostream> #i…

基于SpringBoot+Vue的物流管理系统

运行截图 获取方式 Gitee仓库

机器学习(五) ----------决策树算法

目录 1 核心思想 2 决策树算法主要步骤 3 决策树算法的分类 3.1 ID3算法&#xff08;Iterative Dichotomiser 3&#xff09;&#xff1a; 3.1.1 基本步骤 3.1.2 原理 信息增益 3.1.3 注意事项 3.2 C4.5算法&#xff1a; 3.2.1. 信息增益率 计算公式 3.2.2. 构建决策…