首页 > 其他分享 >数组找出单身狗经典问题

数组找出单身狗经典问题

时间:2022-09-28 16:37:21浏览次数:44  
标签:sz 找出 单身 int arr 异或 数组

前言

单身狗问题是大厂近几年的一个热门考点,所以我们就一起来探讨一下吧!

摘要

单身狗的问题解法有很多种,今天我带给大家两种经典解法,一、数组比较法,二、异或法,这两种解法我会分开来讲。思路我放在具体板块讲解

一、数组比较法(两只狗)

首先呢,我们要用数组比较,就需要把元素两两比较,当一个数出现两次,使之相减,结果为0的话不是单身狗,反之,这就是我们判断出单身狗的条件,但是如果数组乱序的话相邻元素比较可能为0也可能不为0严重影响判断条件,所以我们使用冒泡排序将数组排序,然后将相邻元素两两比较,碰到“情侣”,就跳过,遇见“单身狗”,则输出,注意数组已经排序,所以相比较单身狗一定在左边(即下标小的元素)

代码解释:首先顶定义一个数组arr,再定义一个num用来存储单身狗元素,冒泡排序函数bubble_sort(如果有小伙伴不了冒泡排序,我会在后续博客中更新,简单说一下思路:讲究n个元素一共排几趟,一趟需要交换机此元素分别由两个for循环控制),单身狗函数思路,相邻两元素相比,如果发现单身狗则存入num数组,使用k来控制循环结束,最总方可找出单身狗6,9

//排序比较法
//void bubble_sort(int arr[], int sz)
//{
// int i = 0;
//
// for (i = 0; i < sz - 1; i++)//一趟
// {
// int j = 0;
// for (j = 0; j < sz - 1 - i; j++)//一趟交换的次数
// {
// if (arr[j] > arr[j + 1])
// {
// int tmp = arr[j];
// arr[j] = arr[j + 1];
// arr[j + 1] = tmp;
// }
// }
// }
//}
//void find(int* arr, int sz,int* num)
//{
// int i = 0;
// int k = 0;
// while (i<sz)
// {
// if ((arr[i] - arr[i + 1]) == 0)
// {
// i = i + 2;
// }
// else
// {
// num[k] = arr[i];//把单身狗放入num数组
// i++;
// k++;
// if (k == 2)
// {
// break;
// }
// }
// }
//}
//int main()
//{
// int arr[] = { 2,1,4,1,2,5,5,4,6,9 };
// int num[2] = { 0 };//存放单身狗元素
// //先使用冒泡排序进行排序
// int sz = sizeof(arr) / sizeof(arr[0]);
// bubble_sort(arr,sz);//排序函数
// find(arr, sz, num);//找单身狗函数
// int i = 0;
// for (i=0;i<2;i++)
// {
// printf("%d ", num[i]);//打印单身狗元素
// }
// return 0;
//}

数组找出单身狗经典问题_c语言

二、异或法(两只狗)

在讲解异或法之前我们先介绍一下异或准则:相同为零,不同为1,看图解

数组找出单身狗经典问题_冒泡排序_02

异或法(一只狗)

了解异或后我们先了解一下一只单身狗怎么解,因为相同为零,不同为1,所以将整个数组一起异或,只有出现两次的数字才会异或得0,而得出的最总结果就是单身狗值

数组找出单身狗经典问题_c语言_03

//在一个数组中找出单身狗(一个)问题
void main()
{
int arr[] = { 1,2,3,4,5,1,2,3,4 };
int i = 0;
int dog = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < sz; i++)
{
dog = dog ^ arr[i];//用异或(看成二进制运算相同为0,不同为1)
} //这里将数组的元素全部异或运算(0^1^2^3^4^5^1^2^3^4)最终结果为5
printf("%d\n",dog);
return 0;
}

数组找出单身狗经典问题_异或运算_04

那么有了一个单身狗的思路,那么有的小伙伴可能就想了:那么两个单身狗问题也就迎刃而解了,还是将全部元素异或,注意大错特错哦,一个单身狗是因为数组中除了它其他元素都是成对出现,所以最终结果为单身狗值,两个单身狗时,其他成对出现的元素异或后还剩下两单身狗异或,最终结果肯定不是单身狗值,所以换个思路想一想,我们只需要将两个单身狗分开(两组),分别将组中元素异或每组得到的值就是分别为单身狗值了,看图解

根据图解我们依据56异或结果二进制位上得1的位数而判断出56二进制在此位肯定不同(在求出具体在哪位不同,用下标拿出来),从而可以将56分为两组,这里就需要引进一个操作符 >> 右移操作符,将两只单身狗异或结果值与1进行逻辑与 (dog >> pos) & 1 方可判断出第几位是1,并将下标值记录在pos中

注:我们的目标是将56分开分位两组分别异或,至于其他出现了两次相同的元素爱分到那组就哪组都行,反正他俩相同的元素异或为0不会有任何影响,最终得到的还是本组的单身狗值

数组找出单身狗经典问题_冒泡排序_05

int main()
{
int arr[] = { 1,2,3,4,5,1,2,3,4,6 };
int i = 0;
int dog = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < sz; i++)
{
dog = dog ^ arr[i];//用异或(看成二进制运算相同为0,不同为1)
} //这里将数组的元素全部异或运算最终结果为两个单身狗异或结果为3
printf("%d\n",dog);
int pos = 0;//pos作为记录第几位是1的下标
int dog1 = 0;
int dog2 = 0;
for (pos = 0; pos < 32; pos++)//找出第几位是1
{
if ((dog >> pos) & 1)//根据整个数组的异或结果dog,确定第几位是1,因为我们的主要目的是将单身狗分开
{
break;
}
}
for (i=0;i<sz;i++)
{
if ((arr[i] >> pos) &1)//这里就将数据分组了
{
dog1 = dog1 ^ arr[i];//这里是下标 1 组
}
else
{
dog2 = dog2 ^ arr[i];//这里是下标 0 组
}
}
printf("%d %d\n",dog1,dog2);
return 0;
}

数组找出单身狗经典问题_单身狗问题_06


拓展:数组比较法升级版

此方法可以不受单身狗的数量限制,比较灵活

//数组比较法升级版
void bubble_sort(int arr[], int sz)
{
int i = 0;

for (i = 0; i < sz - 1; i++)//一趟
{
int j = 0;
for (j = 0; j < sz - 1 - i; j++)//一趟交换的次数
{
if (arr[j] > arr[j + 1])
{
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
void find(int* arr, int sz)
{
int i = 0;
int k = 0;
while (i<sz)
{
if ((arr[i] - arr[i + 1]) == 0)
{
i = i + 2;
}
else
{
printf("%d\n",arr[i]);
i++;
}
}
}
int main()
{
int arr[] = { 1,2,3,5,1,2,4,5,6,7,8,4};
//先使用冒泡排序进行排序
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr,sz);//排序函数
find(arr, sz);//找单身狗函数
return 0;
}

数组找出单身狗经典问题_c语言_07


留言

欢迎小伙伴们留言评论,如果有错误留言或者私信告诉我,喜欢的话就点赞收藏支持一下吧






标签:sz,找出,单身,int,arr,异或,数组
From: https://blog.51cto.com/u_15784725/5715891

相关文章

  • 把两个数据结构相同的数组(数组下有n个对象)合并成一个数组
    数据拼接有一个数组letarr1=[{name:''lili",age:14},{name:''小明",age:16},{name:''张三",age:24},]letarr2=[{class:"初一二班",gender:"0"},{class:"初......
  • SQL字符串转换为数组
    思路:按指定符号分割字符串,返回分割后的元素个数,方法很简单,就是看字符串中存在多少个分隔符号,然后再加一,就是要求的结果。——返回字符串数组长度函数createfunctionGet......
  • 力扣349(java&python)-两个数组的交集(简单)
    题目:给定两个数组 nums1 和 nums2,返回它们的交集 。输出结果中的每个元素一定是唯一的。我们可以不考虑输出结果的顺序。 示例1:输入:nums1=[1,2,2,1],num......
  • [数组和链表的区别]
    [数组和链表的区别]数组'''数组插入数据因为需要连在一起,如果内存空间不连续就得全体迁移,甚至出现内存空间足够但是由于不在一起而导致无法为数组分配内存。'''链......
  • P4062 Yazid的新生舞会(树状数组)
    Yazid的新生舞会题目描述Yazid有一个长度为\(n\)的序列\(A\),下标从\(1\)至\(n\)。显然地,这个序列共有\(\frac{n\left(n+1\right)}{2}\)个子区间。对于任意一......
  • JS数组去重
    1、方法<!--*@Descripttion:数组去重*@version:0.0.1*@Author:PengShuai*@Date:2022-09-2613:16:04*@LastEditors:PengShuai*@LastEditTime:202......
  • java如何将字节数组写入到一个文件中呢?
    转自: ​​http://www.java265.com/JavaJingYan/202207/16566829303864.html​​字节数组简介:   字节:字节是通过网络传输信息(或在硬盘或内存中存储信息)的单位。在ASCI......
  • Java Script 循环,数组,对象,判断,阶乘,查找-综合运用合集
     输出100个helloworld.for(vari=1;i<=100;i++){console.log("helloworld");}创建一个包含1~100的数组.vararray=[];for(vari=1;i<=100;i+......
  • vue 合并数组
    vue合并两个数组*主要方法 : concatdata(){return{totalData:[],//总总选中的数据disabledData:[],//列表已选中风险数据......
  • leetcode 1640.能否连接形成数组
    1640.能否连接形成数组难度简单132  给你一个整数数组arr,数组中的每个整数互不相同。另有一个由整数数组构成的数组pieces,其中的整数也互不相同。请你以任......