java算法OJ(1)位运算

news2024/11/15 9:16:26


 目录

1.前言

2.正文

2.1位运算符号

2.1俩数相除

2.1.1题目

2.1.2示例

2.1.3题解

2.2二进制求和

2.2.1题目

2.2.2示例

2.2.3题解

2.3只出现一次的数字

2.3.1题目

2.3.2示例

2.3.3题解

2.4只出现一次的数字(进阶版)

2.4.1题目

2.4.2示例

2.4.3 题解

2.6颠倒二进制位

3.小结


 

1.前言

今天来刷一点算法题,今天上手的是一些稍微基础的位运算练习题,关于位运算呢有许多类似于脑筋急转弯的逻辑思路,还是饶有趣味的,废话不多说,直接开始。

2.正文

2.1位运算符号

在算法题目开始之前,我们先基础盘点下位运算的各种操作。

按位与(AND)&

  • 两个操作数的对应位都为1时,结果才为1。
  • 例如:5 & 3,二进制表示为101 & 011,结果是101,即5。

按位或(OR)|

  • 两个操作数的对应位中至少有一个为1时,结果为1。
  • 例如:5 | 3,二进制表示为101 | 011,结果是111,即7。

按位异或(XOR)^

  • 两个操作数的对应位相同则结果为0,不同则结果为1。
  • 例如:5 ^ 3,二进制表示为101 ^ 011,结果是110,即6。

按位非(NOT)~

  • 反转操作数的每一位,将1变为0,0变为1。
  • 例如:~5,二进制表示为11111011(32位补码表示)。

左移(Left Shift)<<

  • 将操作数的二进制表示向左移动指定的位数,右边空出的位补0。
  • 例如:5 << 1,二进制表示为101 << 1,结果是1010,即10。

右移(Right Shift)>>

  • 将操作数的二进制表示向右移动指定的位数,左边空出的位补符号位(正数补0,负数补1)。
  • 例如:5 >> 1,二进制表示为101 >> 1,结果是5,即0。

2.2俩数相除

2.2.1题目

2.2.2示例

2.2.3题解

毕竟刚开始上手位运算算法,很多基本的技巧很不是很熟悉,这里借鉴了评论区一位大哥的思路,非常厉害。

我们先来思考,不通过加减乘除直接运算得到结果,而是通过位运算来解决这个问题,有什么思路呢?

我们可以先拿dividend除以2的31次方开始,此时被除出来的是非常小的数,一步一步向下逼近,直到出现一个n(即循环中的i),使得n>=divisor, 表示我们找到了一个足够大的数,这个数乘以divisor是不大于dividend的,所以我们就可以减去2^n个divisor,依此类推,直到余数小于除数。


下面罗列代码实现思路:

  • 先处理特殊情况:
  1. 当除数或者被除数一个为0,则返回。
  2. 当被除数是范围内最小数且除数为-1,返回答案(该特殊处理的原因是按照以下算法会越界)。
  • 通过用异或来计算是否符号相异。
  • 接着for循环来实现核心思路,当找到n时,对ans以及被除数进行处理。
  • 最后判断正负输出即可。
class Solution {
    public int divide(int dividend, int divisor) {
        if(divisor==0||dividend==0){
            return 0;
        }
        //处理特殊情况,处理掉会溢出得情况
        if(dividend==Integer.MIN_VALUE&&divisor==-1){
            return Integer.MAX_VALUE;
        }
        boolean judge = (dividend^divisor)<0;//判断负数
        long a = Math.abs((long)dividend);
        long b = Math.abs((long)divisor);
        int ans = 0;
        for(int i = 31;i >= 0;i--){
            if(a>>i>=b){
                ans+=(1<<i);
                a-=b<<i;
            }
        }
        return judge ? -ans : ans;
    }
}

2.3二进制求和

2.3.1题目

2.3.2示例

2.3.3题解

这道题可以采用比较朴素的思路,将二进制数先转化为十进制数,相加后再转化为二进制数,但这样就没有利用位运算的思想。在正式讲解之前,先让我分享一个Java 中的一个类,

StringBuilder。


StringBuilder 用于创建可变的字符序列。它提供了一个可变长度的字符序列,可以高效地添加、插入和删除字符。append 方法的使用append(int i): 将一个整数追加到 StringBuilder 对象的末尾。


接下来就是模拟二进制在做加法运算时的代码思路是:

  • 创建一个 StringBuilder 对象 ans 来存储结果。

  • 初始化一个变量 ca 为0,用于存储进位。

  • 使用一个 for 循环遍历两个字符串 ab,从它们的末尾开始逐位相加。循环条件是 i >= 0 || j >= 0,确保至少有一个字符串还没有遍历完。

  • 在每次迭代中,计算当前位的和 sum,包括前一次迭代的进位 ca,以及当前位的值(如果索引有效的话)。通过 a.charAt(i) - '0'b.charAt(j) - '0' 将字符转换为整数。

  • sum 除以2得到新的进位值,并将 sum 对2取余得到当前位的结果,追加到 ans 中。

  • 在循环结束后,检查是否有剩余的进位(即 ca 是否为1),如果有,则追加到 ans 中。

  • 最后,使用 ans.reverse().toString()StringBuilder 中的字符序列反转并转换为字符串,因为二进制加法是从最低位到最高位进行的,而字符串是从最高位到最低位存储的。

class Solution {
    public String addBinary(String a, String b) {
        StringBuilder ans = new StringBuilder();
        int ca = 0;
        for(int i = a.length() - 1, j = b.length() - 1;i >= 0 || j >= 0; i--, j--) {
            int sum = ca;
            sum += i >= 0 ? a.charAt(i) - '0' : 0;
            sum += j >= 0 ? b.charAt(j) - '0' : 0;
            ans.append(sum % 2);
            ca = sum / 2;
        }
        ans.append(ca == 1 ? ca : "");
        return ans.reverse().toString();
    }
}

2.4只出现一次的数字

2.4.1题目

2.4.2示例

2.4.3题解

这道题如果抛开题目中对线性时间复杂度的要求,其实有许多实现思路,比如对出现过的数字都进行标记,哪个数字仅标记一次则为答案。但既然咱们是位运算主题,那咱们就来分享这道题利用位运算的神奇操作。


我们知道,当一个数a与0异或操作时,则返回a;当a与a异或操作时,则返回0。那么我们就有一个大胆的想法,将数组中所有的数字进行异或操作,但凡出现过俩次的数经过异或全部变为0,最终保留下来的数即为最终答案。当时我看完题解的时候,也被这个思路深深的震撼到了。接下来附上代码:

class Solution {
    public int singleNumber(int[] nums) {
        int ans = 0;
        for(int num:nums){
            ans^=num;
        }
        return ans;
    }
}

还是再感叹一句,这思路绝了。

2.5只出现一次的数字(进阶版)

2.5.1题目

2.5.2示例

2.5.3 题解

这道题是上一道题的进阶版,我们也是按照位运算的思路进行解决问题。

核心思路是我们只需要累计计算各个数字每一位的加和,可以很轻松的出一个结论是,当末位之和取模3时如果正好为0,则仅出现一次的数的该二进制位置也为0;同理如果取模3为1,则仅出现一次的数的该二进制位置也为1.

class Solution {
    public int singleNumber(int[] nums) {
        int ans = 0;
        for(int i = 0;i<=31;i++){
            int total = 0;
            for(int num : nums){
                total+=(num>>i)&1;
            }
            if(total%3!=0){
                ans|=(1<<i);
            }
        }
        return ans;
    }
}

2.6颠倒二进制位

2.6.1题目

2.6.2示例

2.6.3 题解

public class Solution {
    // you need treat n as an unsigned value
    public int reverseBits(int n) {
        int ans = 0;
        for(int i = 0;i <= 31;i++){
            int num = (n & 1);
            ans |=num << ( 31 - i );
            n>>>=1;
        }
        return ans;
    }
}

3.小结

今天的分享到这里就结束了哦,喜欢的小伙伴们点点赞点点关注,你的支持就是对我最大的鼓励!

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

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

相关文章

glb数据格式

glb数据格式 glb 文件格式只包含一个glb 文件&#xff0c;文件按照二进制存储&#xff0c;占空间小 浏览 浏览glb工具的很多&#xff0c;ccs&#xff0c;3D查看器等都可以&#xff0c;不安装软件的话用下面网页加载就可以&#xff0c;免费 glTF Viewer (donmccurdy.com) glb…

uniapp小程序中通过uni.setClipboardData实现复制功能无效的原因和解决方案

// 复制下载链接const shareFile (filePath) > {const pdfUrl 复制内容uni.showModal({title: 下载提示,content: 请复制链接到浏览器中下载,confirmColor: #eb2444,confirmText: 复制链接,success(res) {if (res.confirm) {uni.setClipboardData({data: pdfUrl, // url地…

C++: unordered系列关联式容器

目录 1. unordered系列关联式容器1.1 unordered_map1.2 unordered_set 2. 哈希概念3. 哈希冲突4. 闭散列5. 开散列 博客主页: 酷酷学 感谢关注!!! 正文开始 1. unordered系列关联式容器 在C98中&#xff0c;STL提供了底层为红黑树结构的一系列关联式容器&#xff0c;在查询时…

【笔记】自动驾驶预测与决策规划_Part4_时空联合规划

文章目录 0. 前言1. 时空联合规划的基本概念1.1 时空分离方法1.2 时空联合方法 2.基于搜索的时空联合规划 &#xff08;Hybrid A* &#xff09;2.1 基于Hybrid A* 的时空联合规划建模2.2 构建三维时空联合地图2.3 基于Hybrid A*的时空节点扩展2.4 Hybrid A* &#xff1a;时空节…

多线程——“死锁”

目录 前言 一、一个线程&#xff0c;一把锁 1.问题介绍 2.可重入锁 二、两个线程&#xff0c;两把锁 1.问题介绍 2.解决方式 三、N个线程&#xff0c;M把锁 1.哲学家就餐问题 2.解决方式 结尾 前言 “死锁”是多线程代码中一类常见的问题&#xff0c;加锁是能解决线…

plt的简单使用

目录 介绍示例 介绍 plt 是 Python 中 Matplotlib 库的一个常用别名&#xff0c;它表示 pyplot&#xff0c;这是一个用于创建图形和图形的可视化表示的工具。下面是一些 plt 函数的详解和示例&#xff0c;以帮助大家理解和使用。 示例 示例1&#xff1a; import matplotlib…

AV1 Bitstream Decoding Process Specification--[9]:语法结构语义-5

原文地址&#xff1a;https://aomediacodec.github.io/av1-spec/av1-spec.pdf 没有梯子的下载地址&#xff1a;AV1 Bitstream & Decoding Process Specification摘要&#xff1a;这份文档定义了开放媒体联盟&#xff08;Alliance for Open Media&#xff09;AV1视频编解码…

loadrunner个人笔记

创建场景配置&#xff1a; 两个同时 去四&#xff1a;日志、时间、模拟、其他自动事务 加一&#xff1a;首选项 1、写脚本&#xff0c;沟通官方、文件打印扫描 MFI-sw.support.gsd.imsc.sda.globalopentext.com support.casemicrofocus.com 支持资源 | Micro Focus | OpenT…

【毕业论文+源码】基于ASP的课程指导平台的开发

引 言 随着全球信息化技术的兴起&#xff0c;特别是Internet的日益普及&#xff0c;解决了信息Internet上传递的问题&#xff0c;建立了一个组织得很好的信息结构框架&#xff0c;使得Internet用户能够在Internet上的任何一个终端&#xff0c;以一种简单、统一的方式来访问超…

Leetcode Hot 100刷题记录 -Day18(反转链表)

反转链表&#xff1a; 问题描述&#xff1a; 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1]示例 2&#xff1a; 输入&#xff1a;head [1,2] 输出&a…

视频监控相关笔记

一、QT 之 QTreeWidget 树形控件 Qt编程指南&#xff0c;Qt新手教程&#xff0c;Qt Programming Guide 一个树形结构的节点中的图表文本 、附带数据的添加&#xff1a; QTreeWidgetItem* TourTreeWnd::InsertNode(NetNodeInfo node, QTreeWidgetItem* parent_item) { // …

回文子串通用做法

647. 回文子串 先引出力扣链接 给定一个字符串&#xff0c;你的任务是计算这个字符串中有多少个回文子串。 具有不同开始位置或结束位置的子串&#xff0c;即使是由相同的字符组成&#xff0c;也会被视作不同的子串。示例 1&#xff1a; 输入&#xff1a;"abc" 输出…

for循环的应用

正三角 for (int i 0; i < 8; i) { for (int j 0; j < 15; j) { int kong 8 - i - 1; int star 2 * i 1; if (j < kong) { Console.Write(" "); } else if (j < kong star)…

【LLM学习之路】9月23日24日 第十、十一天 Attention代码解读

【LLM学习之路】9月23日24日 第十、十一天 Attention代码解读 Transformer模型大致分为三类 纯 Encoder 模型&#xff08;例如 BERT&#xff09;&#xff0c;又称自编码 (auto-encoding) Transformer 模型&#xff1b;纯 Decoder 模型&#xff08;例如 GPT&#xff09;&#…

多颜色绘制语义分割/变化检测结果图

在论文绘图时&#xff0c;传统的二元语义分割结果图颜色单一&#xff08;下图左&#xff09;&#xff0c;所以论文中常根据混淆矩阵类别使用多颜色进行绘制&#xff08;下图右&#xff09;&#xff0c;可以看到&#xff0c;结果的可视化效果更好。 以下是绘制代码&#xff1a; …

同等学力申硕英语网课如何选择

很多考生想知道同等学力申硕英语网课如何选择&#xff0c;小编告诉大家&#xff0c;首先明确自己的学习目标和需求是为了提高口语、阅读、写作还是听力能力? 只有明确了自己的学习目标和需求&#xff0c;才能更好地选择适合自己的课程和平台。 二、选择知名品牌和口碑良好的平…

UE5地图白屏/过曝/非常亮の解决方法

今天遇到一个问题 , 新建项目 , 打开虚幻第三人称地图的默认关卡 , 发现白屏 , 啥也看不见 猜测可能是虚幻编辑器的bug , 造成白屏的原因应该是场景过曝了 记录一下解决方案 第一种解决方法 找到场景中的 后期处理体积 (PostProcessVolume) 直接删掉 或者找到 细节面板中 -…

衍射的角谱理论

一、单色平面波与本征函数 不考虑夫琅禾费近似, 则相干光场在给定二平面间的传播过程就是通过一个二维线性空不变系统。 上式函数是这个系统的本征函数,表示振幅为1的平面波在xy平面上的复振幅分布,空间频率分量 = cos / , = cos / 与平面波的传播方向相联系, 空间…

java和mysql命名规则不一样,每次在mybatis中起别名太麻烦?来看看如何设置自动自动映射!

简介&#xff1a; 在 Java 开发中&#xff0c;当使用 MyBatis 框架连接 Java 代码与 MySQL 数据库时&#xff0c;常常会遇到 Java 和 MySQL 命名规则不一致的问题&#xff0c;这使得每次在 MyBatis 中为查询结果起别名变得繁琐。本教程将深入探讨如何设置自动映射&#xff0c;以…

java节假日工具类,判断一个日期是否是法定节假日

java节假日工具类&#xff0c;判断一个日期是否是法定节假日 1.HolidayUtil工具类2.工具类生成的日期json文件3.结果展示 无需链接数据库&#xff0c;无需手写节假日集合列表 1.HolidayUtil工具类 import com.alibaba.fastjson.JSONObject; import com.fasterxml.jackson.data…