LeetCode 面试题 16.09. 运算
文章目录
- 一、题目
- 二、C# 题解
一、题目
请实现整数数字的乘法、减法和除法运算,运算结果均为整数数字,程序中只允许使用加法运算符和逻辑运算符,允许程序中出现正负常数,不允许使用位运算。
你的实现应该支持如下操作:
Operations()
构造函数minus(a, b)
减法,返回a - b
multiply(a, b)
乘法,返回a * b
divide(a, b)
除法,返回a / b
示例:
Operations operations = new Operations();
operations.minus(1, 2); //返回-1
operations.multiply(3, 4); //返回12
operations.divide(5, -2); //返回-2
提示:
- 你可以假设函数输入一定是有效的,例如不会出现除法分母为0的情况
- 单个用例的函数调用次数不会超过1000次
点击此处跳转题目。
二、C# 题解
使用常数数组 Poss
和 Negs
分别记录 2 次幂的正负值,便于后续使用。
P o s s : { 2 0 2 1 2 2 2 3 2 4 2 5 2 6 2 7 } N e g s : { − 2 0 − 2 1 − 2 2 − 2 3 − 2 4 − 2 5 − 2 6 − 2 7 } \begin{array}{l} \hspace{0.15em}Poss:\{\hspace{0.78em} 2^0 \hspace{2.2em} 2^1 \hspace{2.25em} 2^2 \hspace{2.4em} 2^3 \hspace{2.1em} 2^4 \hspace{2.25em} 2^5 \hspace{2.25em} 2^6 \hspace{2.1em} 2^7\} \\ Negs:\{-2^0 \hspace{1em} -2^1 \hspace{1em} -2^2 \hspace{1.2em} -2^3 \hspace{0.9em} -2^4 \hspace{1em} -2^5 \hspace{1em} -2^6 \hspace{0.9em} -2^7\} \\ \end{array} Poss:{2021222324252627}Negs:{−20−21−22−23−24−25−26−27}
Negative(int a)
:
如果 a 是正数,则遍历负数数组Negs
;如果 a 是负数,则遍历正数数组Poss
。每次遍历判断相加后是否溢出,如果不溢出,就相加,否则跳过。
溢出判断条件:ans + nums[i] + a
与a
异号,则溢出。
a : 13 ⟵ 方向 n u m s : { − 2 0 ‾ − 2 1 − 2 2 ‾ − 2 3 ‾ − 2 4 − 2 5 − 2 6 − 2 7 } ↑ ↑ ↑ a n s : ( − 1 ) + ( − 4 ) + ( − 8 ) = − 13 \begin{array}{l} \hspace{2em}a:13\\ \hspace{25.9em} \longleftarrow 方向\\ nums:\{\underline{\bold{-2^0}} \hspace{1em} -2^1 \hspace{1em} \underline{\bold{-2^2}} \hspace{1.2em} \underline{\bold{-2^3}} \hspace{0.9em} -2^4 \hspace{1em} -2^5 \hspace{1em} -2^6 \hspace{0.9em} -2^7\} \\ \hspace{4.5em} \uparrow \hspace{5.6em} \uparrow \hspace{2.6em} \uparrow \\ \hspace{0.9em}ans:\hspace{0.3em} (-1) \hspace{1.35em} + \hspace{1.35em} (-4) \hspace{0em} + \hspace{0em} (-8) \hspace{12.5em} = -13\ \end{array} a:13⟵方向nums:{−20−21−22−23−24−25−26−27}↑↑↑ans:(−1)+(−4)+(−8)=−13
-
Minus(int a, int b)
:
即 a + Negative(b)。 -
Multipy(int a, int b)
:
类似 Negative(int a) 的思想,Negative(int a) 可以看做是 Multipy(-1, int a),因此将 nums 数组扩展为 a * 2i 即可求解 a * b。在求解 -b 时(记为 cnt),累加 a * 2i,即可得到答案。
这里需要注意 a 的符号,如果 b < 0,需要将 a 异号。
a : 5 b : − 13 c n t : ( − 1 ) + ( − 4 ) + ( − 8 ) = − 13 ↓ ↓ ↓ c n t s : { 2 0 ‾ 2 1 2 2 ‾ 2 3 ‾ 2 4 2 5 2 6 2 7 } ⟵ 方向 n u m s : { − 5 ∗ 2 0 ‾ − 5 ∗ 2 1 − 5 ∗ 2 2 ‾ − 5 ∗ 2 3 ‾ − 5 ∗ 2 4 − 5 ∗ 2 5 − 5 ∗ 2 6 − 5 ∗ 2 7 } ↑ ↑ ↑ a n s : ( − 5 ∗ 1 ) + ( − 5 ∗ 4 ) + ( − 5 ∗ 8 ) = − 5 ∗ 13 \begin{array}{l} \hspace{2em}a:5 \hspace{2em} b:-13\\\\ \hspace{1.1em} cnt: \hspace{1.1em} (-1) \hspace{2.9em} + \hspace{2.9em} (-4) \hspace{0.8em} + \hspace{0.8em} (-8) \hspace{19em} = -13\\ \hspace{5.2em} \downarrow \hspace{8.7em} \downarrow \hspace{4.2em} \downarrow \\ \hspace{0.6em} cnts: \{ \hspace{1.2em} \underline{\bold{2^0}} \hspace{3.6em} 2^1 \hspace{3.6em} \underline{\bold{2^2}} \hspace{3.6em} \underline{\bold{2^3}} \hspace{3.6em} 2^4 \hspace{3.6em} 2^5 \hspace{3.6em} 2^6 \hspace{3.6em} 2^7 \hspace{0.9em} \}\\\\ \hspace{38em} \longleftarrow 方向\\\\ nums:\{\underline{\bold{-5*2^0}} \hspace{1em} -5*2^1 \hspace{1em} \underline{\bold{-5*2^2}} \hspace{1.2em} \underline{\bold{-5*2^3}} \hspace{0.9em} -5*2^4 \hspace{1em} -5*2^5 \hspace{1em} -5*2^6 \hspace{0.9em} -5*2^7\} \\ \hspace{5.2em} \uparrow \hspace{8.7em} \uparrow \hspace{4.2em} \uparrow \\ \hspace{0.9em}ans:\hspace{0.3em} (-5*1) \hspace{2.2em} + \hspace{2.2em} (-5*4) \hspace{0em} + \hspace{0em} (-5*8) \hspace{18.5em} = -5*13\\ \end{array} a:5b:−13cnt:(−1)+(−4)+(−8)=−13↓↓↓cnts:{2021222324252627}⟵方向nums:{−5∗20−5∗21−5∗22−5∗23−5∗24−5∗25−5∗26−5∗27}↑↑↑ans:(−5∗1)+(−5∗4)+(−5∗8)=−5∗13
Divide(int a, int b)
:
对 b 进行扩展为 nums,即 nums = b * Poss(若 a、b 异号,则 b 取反,目的是使 nums 符号与 a 相同),让 a 尝试依次减去 nums[i],能减则减,减去后 ans 加上对应的 cnts[i](若 a、b 异号,则 cnts 数组为负值;反之,cnts 数组为正值)。是否选取第 i 个元素的条件:
1. a > 0,则 sum + nums[i] <= a。
2. a < 0,则 sum + nums[i] >= a。
a : − 67 b : 5 a n s : ( − 1 ) + ( − 4 ) + ( − 8 ) = − 13 ↓ ↓ ↓ c n t s : { − 2 0 ‾ − 2 1 − 2 2 ‾ − 2 3 ‾ − 2 4 − 2 5 − 2 6 − 2 7 } ⟵ 方向 n u m s : { − 5 ∗ 2 0 ‾ − 5 ∗ 2 1 − 5 ∗ 2 2 ‾ − 5 ∗ 2 3 ‾ − 5 ∗ 2 4 − 5 ∗ 2 5 − 5 ∗ 2 6 − 5 ∗ 2 7 } ↑ ↑ ↑ s u m : ( − 65 ) ← ( − 60 ) ← ( − 40 ) = − 5 ∗ 13 \begin{array}{l} \hspace{2em}a:-67 \hspace{2em} b:5\\\\ \hspace{0.9em} ans: \hspace{1.1em} (-1) \hspace{2.9em} + \hspace{2.9em} (-4) \hspace{0.8em} + \hspace{0.8em} (-8) \hspace{19em} = -13\\ \hspace{5.2em} \downarrow \hspace{8.7em} \downarrow \hspace{4.2em} \downarrow \\ \hspace{0.6em} cnts: \{ \hspace{0.8em} \underline{\bold{-2^0}} \hspace{2.6em} -2^1 \hspace{2.6em} \underline{\bold{-2^2}} \hspace{2.6em} \underline{\bold{-2^3}} \hspace{2.6em} -2^4 \hspace{2.5em} -2^5 \hspace{2.4em} -2^6 \hspace{2.4em} -2^7 \hspace{0.4em} \}\\\\ \hspace{38em} \longleftarrow 方向\\\\ nums:\{\underline{\bold{-5*2^0}} \hspace{1em} -5*2^1 \hspace{1em} \underline{\bold{-5*2^2}} \hspace{1.2em} \underline{\bold{-5*2^3}} \hspace{0.9em} -5*2^4 \hspace{1em} -5*2^5 \hspace{1em} -5*2^6 \hspace{0.9em} -5*2^7\} \\ \hspace{5.2em} \uparrow \hspace{8.7em} \uparrow \hspace{4.2em} \uparrow \\ \hspace{0.6em}sum:\hspace{0.9em} (-65) \hspace{2.5em} \leftarrow \hspace{2.5em} (-60) \hspace{0.3em} \leftarrow \hspace{0.3em} (-40) \hspace{18.8em} = -5*13\\ \end{array} a:−67b:5ans:(−1)+(−4)+(−8)=−13↓↓↓cnts:{−20−21−22−23−24−25−26−27}⟵方向nums:{−5∗20−5∗21−5∗22−5∗23−5∗24−5∗25−5∗26−5∗27}↑↑↑sum:(−65)←(−60)←(−40)=−5∗13
public class Operations {private static long[] Negs, Poss;private const int NEG_ONE = -1;private const int ARR_LEN = 32;static Operations() {long p = 1, n = -1;Poss = new long[ARR_LEN];Negs = new long[ARR_LEN];for (int i = 0; i < ARR_LEN; i++) { // 初始化正、负数组Poss[i] = p;p += p;Negs[i] = n;n += n;}}public int Minus(int a, int b) {return (int)(a + Negative(b));}public int Multiply(int a, int b) {if (a == 0 || b == 0) return 0;long p = b > 0 ? a : Negative(a), ans = 0, cnt = 0;long[] cnts = b > 0 ? Negs : Poss, nums = new long[ARR_LEN];for (int i = 0; i < ARR_LEN; i++) { // 初始化记录数组nums[i] = p;p += p;}// 计算 -b 的过程中,同比例计算 ansfor (int i = ARR_LEN + NEG_ONE; i >= 0; i += NEG_ONE) {if (SameSignal(cnt + cnts[i] + b, b)) {cnt += cnts[i];ans += nums[i];}if (cnt + b == 0) return (int)ans;}return (int)ans;}public int Divide(int a, int b) {if (a == 0) return 0;long p = SameSignal(a, b) ? b : Negative(b), sum = 0, ans = 0;long[] cnts = SameSignal(a, b) ? Poss : Negs, nums = new long[ARR_LEN];for (int i = 0; i < ARR_LEN; i++) { // 初始化记录数组nums[i] = p;p += p;}for (int i = ARR_LEN + NEG_ONE; i >= 0; i += NEG_ONE) {// a > 0,则用 <= 判断溢出,a < 0,则用 >= 判断溢出if (a > 0 && sum + nums[i] <= a || a < 0 && sum + nums[i] >= a) {sum += nums[i];ans += cnts[i];}}return (int)ans;}// 求 -apublic long Negative(long a) {if (a == 0) return 0;long[] nums = a > 0 ? Negs : Poss; // 寻找与 a 异号的数组long ans = 0;for (int i = ARR_LEN + NEG_ONE; i >= 0; i += NEG_ONE) { // 绝对值大 -> 小遍历if (SameSignal(ans + nums[i] + a, a)) // ans + nums[i] 未溢出,则加上 nums[i]ans += nums[i];if (ans + a == 0) return ans; // 提前返回}return ans;}// 判断 a、b 符号是否相同// 0 既看作正数也看作负数public bool SameSignal(long a, long b) {return a <= 0 && b <= 0 || a >= 0 && b >= 0;}
}/*** Your Operations object will be instantiated and called as such:* Operations obj = new Operations();* int param_1 = obj.Minus(a,b);* int param_2 = obj.Multiply(a,b);* int param_3 = obj.Divide(a,b);*/
- 时间:104 ms,击败 80.00% 使用 C# 的用户
- 内存:48.40 MB,击败 0.00% 使用 C# 的用户
相关文章:
LeetCode 面试题 16.09. 运算
文章目录 一、题目二、C# 题解 一、题目 请实现整数数字的乘法、减法和除法运算,运算结果均为整数数字,程序中只允许使用加法运算符和逻辑运算符,允许程序中出现正负常数,不允许使用位运算。 你的实现应该支持如下操作:…...

spring-代理模式
代理模式 一、概念1.静态代理2.动态代理 一、概念 ①介绍 二十三种设计模式中的一种,属于结构型模式。它的作用就是通过提供一个代理类,让我们在调用目标 方法的时候,不再是直接对目标方法进行调用,而是通过代理类间接调用。让不…...

我用好说 AI 做二次元人设
你有没有想过自己做一部原创作品? 就像开发《星露谷物语》那样,自己把控作品的 角色、故事、载体、宣传 等方方面面,让 idea 不再只是灵光一闪。 以前是 “万事开头难”,可能第一步都举步维艰。但现在有了 AI 就不同了ÿ…...

付费阅读微信小程序源码/小程序和公众号双版本-多种付费模式前后端+独立源码
源码简介: 付费阅读微信小程序源码,这个是小程序和公众号双版本,它支持多种付费模式前后端独立源码。能够支持免费观看部分文字、视频和音频内容,而其他部分则需要付费才能继续观看。这样更方便变现。 这是付费阅读微信小程序合…...
ref、reactive、toRef、toRefs
ref 作用:定义一个响应式数据 语法:const xxx ref(initValue) 创建一个包含响应式数据的引用对象 js中操作数据:xxx.value 模板中读取数据:不需要.value,直接<div>{{xxx}}</div> 接收的数据:基本类型、对…...
GPT实战系列-如何用自己数据微调ChatGLM2模型训练
GPT实战系列-如何用自己数据微调ChatGLM2模型训练 目录 GPT实战系列-如何用自己数据微调ChatGLM2模型训练1、训练数据广告文案生成模型训练和测试数据组织: 2、训练脚本3、执行训练调整运行 4、问题解决问题一问题二问题三问题四 1、训练数据 广告文案生成模型 输…...

【数电知识点_2023.10.28】
数制与码制 十进制转二进制 8 bits 1 Byte 2|12 //121100自下而上 商为0为止 2|_ 6_…0 2|_ 3_…0 2|1…1 0…1 0.375 //0.3750.011自上而下 小数点为0为止 x 2 ———— 0.75…0 x 2 ———— 1.5…1 x 2 ———— 1…1 BCD码:每4位二进制表示一位十进制 8421…...

spring boot配置ssl(多cer格式)保姆级教程
1. 准备cer格式的证书; 2. 合并cer证书并转化成jks格式的证书 为啥有这一步,因为cer证书配置在spring boot项目中,项目启动不起来。如果有大佬想指导一下可以给我留言,在此先谢过大佬。 1)先创建一个jks格式的证…...

第2篇 机器学习基础 —(4)k-means聚类算法
前言:Hello大家好,我是小哥谈。聚类算法是一种无监督学习方法,它将数据集中的对象分成若干个组或者簇,使得同一组内的对象相似度较高,不同组之间的对象相似度较低。聚类算法可以用于数据挖掘、图像分割、文本分类等领域…...

【Python爬虫+可视化】解析小破站热门视频,看看播放量为啥会这么高!评论、弹幕主要围绕什么展开
大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 如果有什么疑惑/资料需要的可以点击文章末尾名片领取源码 环境使用 Python 3.8 Pycharm 模块使用 import requests import csv import datetime import hashlib import time 一. 数据来源分析 明确需求 明确采集网站以及数…...
Mac电脑专业三维模型展UV贴图编辑工具RizomUV RS + VS 2023有哪些特点
RizomUV RS VS是一款功能强大的UV展开软件,用于在三维模型上创建和编辑UV贴图。它具有直观的用户界面和丰富的功能,能够帮助艺术家和设计师更高效地进行UV展开工作。 RizomUV RS VS支持多种模型格式,包括OBJ、FBX、DAE和3DS等,使…...
Linux文件描述符和文件指针互转
本文研究的主要是Linux中文件描述符fd与文件指针FILE*互相转换的相关内容,具体介绍如下。 简介 1.文件描述符fd的定义: 文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当…...

C++11线程
C11线程 创建线程 创建线程需要包含头文件<thread>,使用线程类std::thread 构造函数 默认构造函数 thread() noexcept; 默认构造函数,构造一个线程对象,但它不会启动任何实际的线程执行。 任务函数构造函数 template< class Fun…...

VIVO应用商店评论数据抓取
VIVO应用商店的app评论数据抓取 每个应用的评论能获取到最新的 100页 数据 每页20条,也就是 2000条评论数据 接口: pl.appstore.vivo.com.cn/port/comments/ 爬取运行截图:...
第00章_写在前面
第00章_写在前面 讲师:尚硅谷-宋红康(江湖人称:康师傅) 官网:http://www.atguigu.comhttp://www.atguigu.com/) 一、MySQL数据库基础篇大纲 MySQL数据库基础篇分为5个篇章: 1. 数据库概述与MySQL安装篇…...

测绘人注意,你可能会改变历史!
你也许想不到,曾经有一个测绘人员在进行实地测量作业时,在地图上就这么随手一标注,却让这个地方成为了如今的网红打卡地。 这个地方就是外地游客慕名而来的“宽窄巷子”,如果连这个地方都不知道的成都人,就应该不能算…...
MySQL - 慢查询
慢查询日志用于记录执行时间超过设定的时间阈值的 SQL 查询语句。它的目的是帮助数据库管理员识别和优化执行时间较长的查询,以提高数据库性能: 慢查询定义:慢查询日志记录那些执行时间超过 long_query_time 参数设定的时间阈值的 SQL 查询语…...

go中“哨兵错误”的由来及使用建议
“哨兵错误(sentinel error)”这个词的出处。之前我也只是在一些书籍和资料中见到过,也没深究。当这个网友问了我之后,就深入的翻了翻资料,在golang的官方博客中找到了这个词的提法,也算是比较官方的了吧。…...

【Python百练——第2练】使用Python做一个猜数字小游戏
💐作者:insist-- 💐个人主页:insist-- 的个人主页 理想主义的花,最终会盛开在浪漫主义的土壤里,我们的热情永远不会熄灭,在现实平凡中,我们终将上岸,阳光万里 ❤️欢迎点…...

Power BI 傻瓜入门 18. 让您的数据熠熠生辉
本章内容包括: 配置Power BI以使数据增量刷新发现使用Power BI Desktop and Services保护数据集的方法在不影响性能和完整性的情况下管理海量数据集 如果有更新的、更相关的数据可用,旧数据对组织没有好处。而且,老实说,如果数据…...

业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...

XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...

大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...

ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...

初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...