首页 > 编程语言 >算法设计与数据结构系列【超详细、超全面、小白可入,期末复习】持续更新中...

算法设计与数据结构系列【超详细、超全面、小白可入,期末复习】持续更新中...

时间:2024-07-21 19:28:24浏览次数:17  
标签:targetNumber ... return int 可入 number num 数组 数据结构

算法设计与数据结构系列【超详细、超全面、小白可入,期末复习】

持续更新中…

24.07.21

代码采用语言:Java

1、位运算(Bitwise Operation)

  • 常见操作:与(&)、或(I)、非(~)、异或(^
  • 移位运算:>> << 分别为左移和右移
  • >>>运算符:用0填充高位,>>用符号位填充高位,没有<<<运算符

真值表

ab~a~ba&ba|ba^b
1100110
0110011
1001011
0011000

1.1、常见的位运算技巧

  • 判断奇偶数
  • 获取二进制位是1还是0
  • 交换两个整数变量的值
  • 不用判断语句,求出整数的绝对值

1.2、判断奇偶数

使用与运算

  • 奇数二进制的特点:...0100...1 其末尾数字必为1
  • 偶数二进制的特点:...0100...0其末尾数字必为0

故只需将目标数和1做与运算即可得到结果

代码描述

	/**
     * 判断奇偶数-与
     * <p>
     * return true is odd
     *
     * @param number
     * @return
     */
    public static Boolean OddOrEven(int number) {
        return (number & 1) == 1;
    }

1.3、找到落单的数

使用异或运算

题目描述:在一个奇数个元素数组中有且仅有一个数只出现过一次,其余数皆为成双出现,找出这个落单的数字

  • A ^ A = 0
  • A ^ 0 = A

故只需将目标数组中元素依次进行异或运算

第一个与0进行异或

代码描述

	/**
     * 找到落单的数-异或
     * <p>
     * return target number
     *
     * @param targetArray
     * @return
     */
    public static Integer findSingularNumber(int[] targetArray) {
        int targetNumber = 0;
        for (int num : targetArray) {
            targetNumber ^= num;
        }
        return targetNumber;
    }

1.4、找出成双的数

使用异或运算

题目描述:在一个奇数个元素数组中有且仅有一个数只出现过两次,其余数皆出现1次,找出这个成双的数字

只需将目标数组中元素依次进行异或运算

如果结果为0即为目标数字

代码描述

	/**
     * 找出成双的数-异或
     * <p>
     * return target number
     *
     * @param targetArray
     * @return
     */
    public static Integer findPairNumberByXOR(int[] targetArray) {
        int targetNumber = 0;
        for (int num : targetArray) {
            if ((targetNumber ^ num) == 0) {
                break;
            }
            targetNumber = num;
        }
        return targetNumber;
    }

使用辅助空间

遍历目标数组,计数

1、使用数组辅助:数组的下标为目标数组的值,数组对应下标的值为目标数组值出现的次数

2、使用map辅助:key为目标数组的值,value为目标数组值出现的次数

代码描述

	/**
     * 找出成双的数-辅助空间
     * <p>
     * return target number
     *
     * @param targetArray
     * @return
     */
    public static Integer findPairNumberByHelperSpace(int[] targetArray) {
        int targetNumber = 0;
        //辅助空间,1、辅助空间的下标为目标数组的值,辅助空间对应下标的值为目标数组值出现的次数,缺点为目标数组中的值范围不确定
        //这里假设我就假设目标数组中元素最大不超过999,当然你可以使用List
        int[] helperArray = new int[999];
        for (int num : targetArray) {
            helperArray[num]++;
            //如果辅助数组值为2说明此下标出现了两次
            if (helperArray[num] == 2) {
                targetNumber = num;
                break;
            }
        }
        //辅助空间,2、使用map,key为目标数组的值,如果同一个key出现储存两次两次的情况,则此数值为成双数值
        targetNumber = 0;
        Map<Integer, Integer> helperMap = new HashMap<>();
        for (int num : targetArray) {
            boolean isExist = helperMap.containsKey(num);
            if (isExist) {
                //如果存在,则说明此数在此数组出现第二次
                targetNumber = num;
                break;
            } else {
                helperMap.put(num, 1);
            }
        }
        return targetNumber;
    }

1.5、二进制数中1的个数

使用移位运算-移动目标数字相与

  • 1 & 1 = 1
  • 1 & 0 = 0

将目标数字右移和1相与

如果相与结果为1则计数加1

exp:

10110

1:0 & 1 = 0 count + 0 ,10110 >> 1 ==> 1011

2:1 & 1 = 1 count + 1,1011>> 1 ==>101

count = 3

代码实现

	/**
     * 二进制数中1的个数-移动数字
     * <p>
     * return counts
     *
     * @param number
     * @return
     */
    public static Integer findBinary1CountsByMoveNumber(int number) {
        int counts = 0;
        //因为int为4byte即2^32,故须循环32次
        for (int i = 0; i < 32; i++) {
            if (((number >> i) & 1) == 1) {
                counts++;
            }
        }
        return counts;
    }

使用移位运算-移动1相与

将1左移和目标数字相与

exp:

10110

1:0 & 1 = 0 count + 0 ,1 << 1 ==> 10

2:1 & 1 = 1 count + 1,10 << 1 ==>100

count = 3

代码实现

	/**
     * 二进制数中1的个数-移动1
     * <p>
     * return counts
     *
     * @param number
     * @return
     */
    public static Integer findBinary1CountsByMove1(int number) {
        int counts = 0;
        //因为int为4byte即2^32,故须循环32次
        for (int i = 0; i < 32; i++) {
            if ((number & (1 << i)) == (1 << i)) {
                counts++;
            }
        }
        return counts;
    }

使用移位运算-减1相与

将目标数字与目标数字-1相与,直至目标数字为0

过程中相与的次数为1的个数

exp:

10110

10110 - 1 ==> 10101

10110 & 10101 = 10100 每次相与会将最后一个1“抵消”成0

代码实现

	/**
     * 二进制数中1的个数-减1
     * <p>
     * return counts
     *
     * @param number
     * @return
     */
    public static Integer findBinary1CountsBySubtraction1(int number) {
        int counts = 0;
        while (number != 0) {
            counts++;
            number &= (number - 1);
        }
        return counts;
    }

1.6、2的整数幂

使用二进制数中1的个数方法

题目描述:判断一个数是不是2的整数幂

  • 2的整数幂数的特点:二进制数中有且仅有一个1

代码实现

	/**
     * 2的整数幂
     *
     * @param number
     * @return
     */
    public static Boolean isPowerOf2(int number) {
        //选用 二进制数中1的个数 方法之一
        //二进制数中1的个数为1的为2的整数幂
        return (number & (number - 1)) == 0;
    }

标签:targetNumber,...,return,int,可入,number,num,数组,数据结构
From: https://blog.csdn.net/heyiqingsong/article/details/140592302

相关文章

  • 数据结构:栈的基本概念、顺序栈、共享栈以及链栈
    相关概念栈(Stack)是只允许在一端进行插入或删除操作的线性表。栈顶(Top):线性表允许插入删除的那一端。栈底(Bottom):固定的,不允许进行插入和删除的另一端。栈的基本操作InitStack(&S):初始化一个空栈S。StackEmpty(S):判断一个栈是否为空,若栈S为空则返回true,否则返回false。......
  • 初阶数据结构的实现2 双向链表
    1.双向链表1.1概念与结构1.2实现双向链表1.2.1定义程序目标#define_CRT_SECURE_NO_WARNINGS1#pragmaonce#include<stdio.h>#include<assert.h>#include<stdlib.h>#include<stdbool.h>typedefintLTDateType;//定义双向链表结构typedefstructListNode{......
  • 很多logn级别的数据结构,为什么选择B+树?
    高效的范围查询:B+树的叶节点按顺序链接,可以很方便地进行范围查询。与B树不同,B+树的所有叶节点都包含在一个链表中,这使得范围查询和顺序访问非常高效。稳定的查找性能:B+树的所有叶节点在同一层,查找任何一个数据的路径长度都相同,保证了查找操作的时间复杂度为O(logn)。这意味......
  • 08 ES6的for...of和for...in的区别
    在JavaScript中,for...in和for...of是两种不同的循环结构,它们分别在不同的ECMAScript版本中被引入,并且具有不同的用途和特性。for...in循环(ES5)for...in是ECMAScript5(ES5)中引入的,用于遍历对象的可枚举属性和数组的索引。它提供了一种方式来获取对象的键或数组的索引。......
  • 数据结构——栈
    一、栈的定义我们都知道线性表是具有相同数据类型的n(n为表长且n>=0)个数据元素的有限序列。而栈,是只允许在一端进行插入或删除操作的线性表。就如汉罗塔相似,你只能从头顶放入或拿走方块。  重要术语:栈顶、栈底、空栈我们从图就很容易理解这三个术语:空栈:指线性表内......
  • 数据结构:线性表-例题
    顺序存储结构和链式存储结构都可以进行顺序存取。[T/F]顺序存储结构可以进行顺序存取和随机存取;链式存储结构只可以进行顺序存取。散列存储结构能反应数据之间的逻辑关系。[T/F]散列存储通过散列函数映射到物理空间,不能反应数据之间的逻辑关系。链式存储设计时,结点......
  • 【软考】数据结构与算法基础 - 数组和链表
    一、数组和链表的区别(很简单,但是很常考,记得要回答全面)什么是数组:C++语言中,可以用数组,处理一组数据类型相同的数据,不可以动态定义数组的大小(使用前,必须指定大小。)在实际应用中,用户使用数组之前,无法确定数组的大小只能够将数组定义成足够大小,多余出来空间可能不被使用,......
  • 【数据结构】栈和队列
    数据结构是计算机存储、组织数据的方式。栈和队列是两种常用的线性数据结构,它们在程序设计中扮演着重要角色。一、栈(Stack)栈是一种遵循后进先出(LastInFirstOut,LIFO)原则的数据结构。其主要特点如下:1.基本操作:栈的操作主要有两种——压栈(push)和出栈(pop)。压栈:在栈顶插......
  • 用于匹配两个数据列表中的项目的高效数据结构 - python
    我有两个列表,其中一个列表填充ID,另一个列表填充进程名称。多个进程名称可以共享一个ID。我希望能够创建一个可以使用特定ID的数据结构,然后返回与该ID关联的进程列表。我还希望能够使用特定的进程名称并返回与其连接的ID列表。我知道我可以为此创建一个字典,但是I......
  • 我正在尝试理解 lambda...为什么当列表已由 lambda 填充时我不能直接打印列表?
    以下是我在学习网站上找到的代码。callables=[]foriin(1,2,3):callables.append(lambdaa=i:a)forfincallables:print(f())为什么我们不能只打印可调用列表print(callables)如果我这样做print(callables)相反,我得到的输出如下:[......