一个整型数组里除了一个或者两个或者三个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)

寻找数组中只出现一次的数字
这篇博客介绍了一个算法,用于在整型数组中找到出现一次的数字。通过位运算,实现时间复杂度为O(n)、空间复杂度为O(1)的方法。文章分别展示了找出两个和三个唯一数字的C语言实现。
粗糙的给出了分析,最近比较累,以后会改进的。
题目中包括三个小的问题,由简单到复杂:
1,如果只有一个出现一次,考察到异或的性质,就是如果同一个数字和自己异或的活结果为零,那么循环遍历一遍数组,将数组中的元素全部做异或运算,那么出现两次的数字全部异或掉了,得到的结果就是只出现一次的那个数字。
2,如果有两个只出现一次的数字,设定为a,b。也是应用异或,但是数组元素全部异或的结果x=a^b,因为a,b是不相同的数字,因此x肯定不为0。对于x,从低位到高位开始,找到第一个bit位为1的位置设定为第m位,这个第m位的bit肯定来自a或者来自b,不可能同时a,b的第m位(从低到高位)都为1。这样,就可以根据这个第m位就可以把数组分为两个部分,一组为第m位为0,一组为第m位为1.这样,就把问题分解成了求两个数组中只出现一次的数字了。下面首先给这部分的程序和实例分析:
  1. <span style="font-family:FangSong_GB2312;font-size:14px;">#include<stdio.h>  
  2. int get_first_position(int num)  
  3. { //从低位开始找到第一个位1的bit位  
  4.     int index=1;  
  5.     int i=0;  
  6.     while(i<32)  
  7.     {  
  8.         if((num&(1<<i))==(1<<i))  
  9.             break;  
  10.         else  
  11.         {  
  12.             index++;  
  13.             i++;  
  14.         }  
  15.     }  
  16.     return index;  
  17. }  
  18. int is_bit_one(int num,
# 题目重述 编一个C语言程序,定义一个长度为40的整数组 `feedback`,用于保存40个反馈意见。通过函数计算并输出这些反馈的平均值(Mean)、中位数(Median)和众数(Mode)。 - 平均值:所有数的算术平均。 - 中位数:将数组排序后,若个数为偶数,则取中间两个数的平均值。 - 众数:出现次数最多的数(假设唯一)。 --- # 给出答案(答案为带注释的代码块) ```c #include <stdio.h> // 函数声明 void sort(int arr[], int n); double mean(int arr[], int n); double median(int arr[], int n); int mode(int arr[], int n); int main() { int feedback[40]; // 存储40个反馈意见 printf("输入40个反馈意见(整数):\n"); for (int i = 0; i < 40; i++) { scanf("%d", &feedback[i]); } // 计算并输出结果 printf("平均值: %.2f\n", mean(feedback, 40)); printf("中位数: %.2f\n", median(feedback, 40)); printf("众数: %d\n", mode(feedback, 40)); return 0; } // 冒泡排序(升序) void sort(int arr[], int n) { for (int i = 0; i < n - 1; i++) { for (int j = 0; j < n - i - 1; j++) { if (arr[j] > arr[j + 1]) { int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } } // 计算平均值 double mean(int arr[], int n) { int sum = 0; for (int i = 0; i < n; i++) { sum += arr[i]; } return (double)sum / n; } // 计算中位数 double median(int arr[], int n) { sort(arr, n); // 先排序 if (n % 2 == 1) { return arr[n / 2]; } else { return (arr[n / 2 - 1] + arr[n / 2]) / 2.0; } } // 计算众数(假设唯一) int mode(int arr[], int n) { int max_count = 0, mode_value = arr[0]; for (int i = 0; i < n; i++) { int count = 0; for (int j = 0; j < n; j++) { if (arr[j] == arr[i]) { count++; } } if (count > max_count) { max_count = count; mode_value = arr[i]; } } return mode_value; } ``` --- # 代码解析 1. **主函数 `main`**: - 定义数组 `feedback[40]`,通过循环读入40个整数。 - 调用三个函数分别计算均值、中位数和众数,并打印结果。 2. **`sort` 函数**: - 使用冒泡排序对数组进行升序排列,为求中位数做准备。 3. **`mean` 函数**: - 遍历数组累加所有元素,返回总和除以数量 $ \frac{\sum_{i=1}^{n} x_i}{n} $。 4. **`median` 函数**: - 调用 `sort` 排序后,根据奇偶性判断中位数: - 奇数:取中间元素; - 偶数:取中间两元素的平均值 $ \frac{a_{n/2-1} + a_{n/2}}{2} $。 5. **`mode` 函数**: - 双重循环统计每个数出现的次数,记录出现最多次的数值。 --- # 知识点(列出该代码中遇到的知识点) 1. **数组排序(冒泡排序)** 通过嵌套循环比较相邻元素,实现升序排列,便于后续求中位数。 2. **中位数计算方法** 数据有序时,若 $ n $ 为偶数,则中位数为 $ \frac{a_{(n/2)} + a_{(n/2+1)}}{2} $;否则为中间值。 3. **众数统计原理** 利用双重循环统计频次,找出频率最高的元素,假设众数唯一。
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值