剑指offer(C++)-JZ56:数组中只出现一次的两个数字(算法-位运算)

这篇具有很好参考价值的文章主要介绍了剑指offer(C++)-JZ56:数组中只出现一次的两个数字(算法-位运算)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

剑指offer(C++)-JZ56:数组中只出现一次的两个数字(算法-位运算),剑指offer,算法,c++

题目描述:

一个整型数组里除了两个数字只出现一次,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

数据范围:数组长度2≤n≤1000,数组中每个数的大小0<val≤1000000
要求:空间复杂度O(1),时间复杂度O(n)

提示:输出时按非降序排列。

示例:

输入:

[1,4,1,6]

返回值:

[4,6]

说明:

返回的结果中较小的数排在前面   

解题思路:

本题考察位运算。两种解题思路。

1)暴力法

       使用哈希表记录出现频率,将频率为1的数输出即可。该方法的空间复杂度不符合题目要求。

2)异或运算

       异或运算指两个数相同为0,不相同为1。因为除了要寻找的数字出现了一次,其他数字都出现了两次,所以将这些数字进行异或运算后,根据其特性,重复出现的数字抵消了,只保留了出现了一次的数字。

       如4^1^2^1^2。4为100,1为001,2为010,4^1得到101,再^2得到111,再^1得到110,再^2得到100,即4。

       那如果有两个出现了一次的数字,则结果就相当于这两个数字异或。如4^1^2^1^2^3,最终的结果就是111,即4^3。

       本题目要求输出这两个数字,那如何将111拆开呢?4和3,如果某一位不相同,则异或结果该位就是1,我们定义t从001开始,将t与111与运算,寻找哪一位首次出现了1;111中最右即为1,说明在00x的位置,数字4和3是不一样的;再次遍历,将所有数据根据该位的数字分类,这样就能得到两个组,数字为1的组结果就是3,数字为0的组结果就是4。

       不得不说,这题目就是为这个解法量身定做的。。。各个条件完美匹配emm

测试代码:

1)暴力法

class Solution {
public:
    // 寻找出现一次的数字
    vector<int> FindNumsAppearOnce(vector<int>& nums) {
        unordered_map<int,int> um;
        vector<int> result;
        // 遍历数组
        int size = int(nums.size());
        for(int i = 0; i < size; ++i){
            um[nums[i]]++;
        }
        // 寻找出现频率为1的数
        for(int i = 0; i < size; ++i){{
            if(um[nums[i]] == 1){
                result.emplace_back(nums[i]);
            }
        }}
        // 按大小顺序输出
        if(result[0] < result[1]){
            return result;
        }
        else{
            return { result[1], result[0] };
        }
    }
};

2)异或运算文章来源地址https://www.toymoban.com/news/detail-692885.html

class Solution {
public:
    // 寻找出现一次的数字
    vector<int> FindNumsAppearOnce(vector<int>& nums) {
        vector<int> result{ 0, 0};
        // 遍历数组进行异或运算
        int temp = 0;
        int size = int(nums.size());
        for(int i = 0; i < size; ++i){
            temp ^= nums[i];
        }
        // 找到两个数不相同的第一位
        int t = 1;
        while((t & temp) == 0){
            t <<= 1;
        }
        // 再次遍历,将t位为1的数归为1组,为0的数归为1组,这样两组的异或运算得到的结果就是两个不重复数
        for(int i = 0; i < size; ++i){
            if((t & nums[i]) == 0){
                result[0] ^= nums[i];
            }
            else{
                result[1] ^= nums[i];
            }
        }
        // 按大小顺序输出
        if(result[0] < result[1]){
            return result;
        }
        else{
            return { result[1], result[0] };
        }
    }
};

到了这里,关于剑指offer(C++)-JZ56:数组中只出现一次的两个数字(算法-位运算)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 剑指 Offer 39.数组中出现次数超过一半的数字

    剑指 Offer 39.数组中出现次数超过一半的数字 给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 你可以假设数组是非空的,并且给定的数组总是存在多数元素。 示例 1: 输入:nums = [3,2,3] 输出:3 示例 2: 输入:n

    2024年01月21日
    浏览(40)
  • 剑指offer39.数组中出现次数超过一半的数字

    这个题非常简单,解法有很多种,我用的是HashMap记录每个元素出现的次数,只要次数大于数组长度的一半就返回。下面是我的代码: 题解还有一种更牛逼的解法,把数组排序,然后返回数组中间的那个数就行,因为如果这个数出现的次数大于数组长度的一半的话,排完序后

    2024年02月13日
    浏览(37)
  • 剑指offer(C++)-JZ49:丑数(算法-其他)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺

    2024年02月03日
    浏览(43)
  • 剑指offer--JZ6 从尾到头打印链表

    我写不出来,参考别人的代码后理清思路后再写的C语言版本,代码如下: 最难理解的是创建结果数组那里。我竟然不知道有这种语法。我看了老半天。malloc动态申请的内存可以看作数组使用,而且能使用数组的方式来访问元素。 大致讲解下整体思路: 1.创建一个头结点hea

    2024年02月11日
    浏览(54)
  • 剑指offer(C++)-JZ29:顺时针打印矩阵(算法-模拟)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 则依次打印出数字 数据范围: 0 = matrix.length = 100 0 = ma

    2024年02月10日
    浏览(43)
  • 剑指offer(C++)-JZ47:礼物的最大价值(算法-动态规划)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 在一个mtimes nm×n的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向

    2024年02月05日
    浏览(65)
  • 剑指offer(C++)-JZ12:矩阵中的路径(算法-回溯)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 请设计一个函数,用来判断在一个n乘m的矩阵中是否存在一条包含某长度为len的字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以

    2024年02月11日
    浏览(45)
  • 剑指offer(C++)-JZ13:机器人的运动范围(算法-回溯)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 地上有一个 rows 行和 cols 列的方格。坐标从 [0,0] 到 [rows-1,cols-1] 。一个机器人从坐标 [0,0] 的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,

    2024年02月12日
    浏览(47)
  • 剑指offer(C++)-JZ63:买卖股票的最好时机(一)(算法-动态规划)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 假设你有一个数组prices,长度为n,其中prices[i]是股票在第i天的价格,请根据这个价格数组,返回买卖股票能获得的最大收益 1.你可以买入一次股票和卖出一

    2024年02月04日
    浏览(41)
  • 剑指offer(C++)-JZ64:求1+2+3+...+n(算法-位运算)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等及条件判断语句(A?B:C)。 数据范围: 0n≤200 进阶: 空间复杂度 O(1) ,时间复杂

    2024年02月09日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包