java算法OJ(1)位运算


 目录

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.小结

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

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

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

相关文章

【ComfyUI】控制光照节点——ComfyUI-IC-Light-Native

原始代码&#xff08;非comfyui&#xff09;&#xff1a;https://github.com/lllyasviel/IC-Light comfyui实现1&#xff08;600星&#xff09;&#xff1a;https://github.com/kijai/ComfyUI-IC-Light comfyui实现2&#xff08;500星&#xff09;&#xff1a;https://github.c…

cobbler自动批量安装多版本操作系统

本次虚拟化环境为VMware Workstation Pro&#xff0c;cobbler服务端为CentOS7.9&#xff0c;需要自动安装的版本为CentOS7.9和CentOS8.1 目录 一、安装cobbler服务端1、修改YUM源2、关闭防火墙3、安装软件包4、cobbler环境配置5、解决语法问题6、启动服务7、导入镜像8、自定义…

Spring自定义参数解析器

在这篇文章中&#xff0c;我们认识了参数解析器和消息转换器&#xff0c;今天我们来自定义一个参数解析器。 自定义参数解析器 实现HandlerMethodArgumentResolver的类&#xff0c;并注册到Spring容器。 Component&#xff0f;&#xff0f;注册到Spring public class UserAr…

统信服务器操作系统【Cron定时任务服务】

Cron定时任务服务服务介绍、服务管理、服务配置 文章目录 一、功能概述二、功能介绍1. Cron 服务管理2.Cron 服务管理3.Cron 服务配置run-parts一、功能概述 cron是一个可以用来根据时间、日期、月份、星期的组合来 调度对周期性任务执行的守护进程。利用 cron 所提供的功能,可…

第十四届蓝桥杯嵌入式国赛

一. 前言 本篇博客主要讲述十四届蓝桥杯嵌入式的国赛题目&#xff0c;包括STM32CubeMx的相关配置以及相关功能实现代码以及我在做题过程中所遇到的一些问题和总结收获。如果有兴趣的伙伴还可以去做做其它届的真题&#xff0c;可去 蓝桥云课 上搜索历届真题即可。 二. 题目概述 …

七种修复错误:由于找不到msvcr110.dll 无法继续执行的方法

当你在运行某些程序时遇到“找不到msvcr110.dll”的错误提示&#xff0c;这通常意味着你的系统缺少了Microsoft Visual C 2012 Redistributable包中的一个重要文件。这个DLL文件是Microsoft Visual C Redistributable的一部分&#xff0c;用于支持许多使用Visual C编写的软件和…

Elasticsearch:检索增强生成背后的重要思想

作者&#xff1a;来自 Elastic Jessica L. Moszkowicz 星期天晚上 10 点&#xff0c;我九年级的女儿哭着冲进我的房间。她说她对代数一无所知&#xff0c;注定要失败。我进入超级妈妈模式&#xff0c;却发现我一点高中数学知识都不记得了。于是&#xff0c;我做了任何一位超级妈…

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

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

Windows系统的Tomcat日志路径配置

文章目录 引言I Windows系统的Tomcat日志路径配置配置常规日志路径访问日志路径配置,修改server.xmlII 日志文件切割:以分隔割tomcat 的 catalina.out 文件为例子通过Linux系统自带的切割工具logrotate来进行切割引言 需求:C盘空间不足,处理日志文件,tomcat日志迁移到D盘…

Java基础知识扫盲

目录 Arrays.sort的底层实现 BigDecimal(double)和BigDecimal(String)有什么区别 Char可以存储一个汉字吗 Java中的Timer定时调度任务是咋实现的 Java中的序列化机制是咋实现的 Java中的注解是干嘛的 Arrays.sort的底层实现 Arrays.sort是Java中提供的对数组进行排序的…

信用卡存量经营读书笔记

信用卡的各项收益和损失分析表 用杜邦分析法拆利润如下 信用卡要不要烧钱&#xff1f;不要&#xff0c;因为没有网络效应&#xff08;用户量增加带来的优惠比较少&#xff09;和赢家通吃的情况 线上获客的几种方式&#xff1a;引流分成、某个项目的联名信用卡、营业收入分成 …

爬虫到底难在哪里?

如果你是自己做爬虫脚本开发&#xff0c;那确实难&#xff0c;因为你需要掌握Python、HTML、JS、xpath、database等技术&#xff0c;而且还要处理反爬、动态网页、逆向等情况&#xff0c;不然压根不知道怎么去写代码&#xff0c;这些技术和经验储备起码得要个三五年。 比如这几…

【D3.js in Action 3 精译_023】3.3 使用 D3 将数据绑定到 DOM 元素

当前内容所在位置&#xff1a; 第一部分 D3.js 基础知识 第一章 D3.js 简介&#xff08;已完结&#xff09; 1.1 何为 D3.js&#xff1f;1.2 D3 生态系统——入门须知1.3 数据可视化最佳实践&#xff08;上&#xff09;1.3 数据可视化最佳实践&#xff08;下&#xff09;1.4 本…

【开源免费】基于SpringBoot+Vue.JS教师工作量管理系统(JAVA毕业设计)

本文项目编号 T 043 &#xff0c;文末自助获取源码 \color{red}{T043&#xff0c;文末自助获取源码} T043&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

两数之和、三数之和、四数之和

目录 两数之和 题目链接 题目描述 思路分析 代码实现 三数之和 题目链接 题目描述 思路分析 代码实现 四数之和 题目链接 题目描述 思路分析 代码实现 两数之和 题目链接 LCR 179. 查找总价格为目标值的两个商品 - 力扣&#xff08;LeetCode&#xff09; 题目…

算法:69.x的平方根

题目 链接&#xff1a;leetcode链接 思路分析&#xff08;二分算法&#xff09; 当然你可以使用暴力查找&#xff0c;但是二分算法的时间复杂度更好。 我们先用暴力查找找点灵感 x &#xff1a;1 2 3 4 5 6 7 8 x2&#xff1a;1 4 9 16 25 36 49 64 我们的目的是找到一个x…

《程序猿之设计模式实战 · 适配器模式》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

【数据结构初阶】链式二叉树接口实现超详解

文章目录 1. 节点定义2. 前中后序遍历2. 1 遍历规则2. 2 遍历实现2. 3 结点个数2. 3. 1 二叉树节点个数2. 3. 2 二叉树叶子节点个数2. 3. 3 二叉树第k层节点个数 2. 4 二叉树查找值为x的节点2. 5 二叉树层序遍历2. 6 判断二叉树是否是完全二叉树 3. 二叉树性质 1. 节点定义 用…

推荐一款开源的Redis桌面客户端

TinyRDM 是一个现代化的、轻量级的跨平台 Redis 桌面客户端&#xff0c;能在 Mac、Windows 和 Linux 系统上使用。它有着现代化的设计风格&#xff0c;界面既简洁又清晰&#xff0c;操作起来方便又高效。不管是刚开始接触的新手&#xff0c;还是经验丰富的开发者&#xff0c;都…

软考(9.22)

1 在浏览器的地址栏中输入xxxyftp.abc.can.cn&#xff0c;在该URL中( )是要访问的主机名。 A.xxxyftp B.abc C.can D.cn 协议://主机名.域名.域名后缀或IP地址(:端口号)/目录/文件名。 本题xxxyftp是主机名&#xff0c;选择A选项。 2 假设磁盘块与缓冲区大小相同&#xff0c;…