⭐算法入门⭐《二分枚举》中等01 —— LeetCode 面试题 16.21. 交换和
Posted 英雄哪里出来
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了⭐算法入门⭐《二分枚举》中等01 —— LeetCode 面试题 16.21. 交换和相关的知识,希望对你有一定的参考价值。
🔥让天下没有难学的算法🔥
C语言免费动漫教程,和我一起打卡! 🌞《光天化日学C语言》🌞
入门级C语言真题汇总 🧡《C语言入门100例》🧡
几张动图学会一种数据结构 🌳《画解数据结构》🌳
组团学习,抱团生长 🌌《算法入门指引》🌌
竞赛选手金典图文教程 💜《夜深人静写算法》💜
一、题目
1、题目描述
给定两个整数数组,请交换一对数值(每个数组中取一个数值),使得两个数组所有元素的和相等。返回一个数组,第一个元素是第一个数组中要交换的元素,第二个元素是第二个数组中要交换的元素。若有多个答案,返回任意一个均可。若无满足条件的数值,返回空数组。
样例输入:array1 = [4, 1, 2, 1, 1, 2], array2 = [3, 6, 3, 3]
样例输出:[1, 3]
2、基础框架
- C语言 版本给出的基础框架代码如下:
int* findSwapValues(int* array1, int array1Size, int* array2, int array2Size, int* returnSize){
}
3、原题链接
二、解题报告
1、思路分析
1)首先,对第一个数组进行不降排序,然后对所有数求和为
s
u
m
1
sum1
sum1,那么第一个数组可以选择的数就是
x
x
x 和
s
u
m
1
−
x
sum1-x
sum1−x;
2)然后,对第二个数组进行不降排序,然后对所有数求和为
s
u
m
2
sum2
sum2,那么第二个数组可以选择的数就是
y
y
y 和
s
u
m
2
−
y
sum2-y
sum2−y;
3)现在要达到的目的就是
x
+
s
u
m
2
−
y
=
y
+
s
u
m
1
−
x
x+sum2-y = y+sum1-x
x+sum2−y=y+sum1−x化简以后得到:
2
x
=
2
y
+
s
u
m
1
−
s
u
m
2
2x = 2y + sum1-sum2
2x=2y+sum1−sum2
4)枚举
x
x
x, 得到
y
=
(
2
x
−
s
u
m
1
+
s
u
m
2
)
/
2
y = (2x-sum1+sum2)/2
y=(2x−sum1+sum2)/2 去数组2里查找是否存在这个
y
y
y 就完事了;
2、时间复杂度
- 二分枚举答案,时间复杂度为 O ( l o g 2 n ) O(log_2n) O(log2n)。
3、代码详解
int cmp(const void *a, const void *b) {
return *(int *)a - *(int *)b;
}
int search(int* nums, int numsSize, int target){
int l = 0, r = numsSize - 1;
while(l <= r) {
int mid = (l + r) >> 1;
if(target == nums[mid]) {
return mid;
}else if(target > nums[mid]) {
l = mid + 1;
}else {
r = mid - 1;
}
}
return -1;
}
int* findSwapValues(int* array1, int array1Size, int* array2, int array2Size, int* returnSize){
int i, x, y, sum1 = 0, sum2 = 0;
int *ret = NULL;
qsort(array1, array1Size, sizeof(int), cmp); // (1)
qsort(array2, array2Size, sizeof(int), cmp); // (2)
for(i = 0; i < array1Size; ++i) {
sum1 += array1[i]; // (3)
}
for(i = 0; i < array2Size; ++i) {
sum2 += array2[i]; // (4)
}
for(i = 0; i < array1Size; ++i) {
x = array1[i];
y = 2*x - sum1 + sum2;
if(y & 1) {
continue; // (5)
}
y >>= 1; // (6)
if( search(array2, array2Size, y ) != -1) {
ret = (int *)malloc(2 * sizeof(int)); // (7)
ret[0] = x;
ret[1] = y;
*returnSize = 2;
return ret;
}
}
*returnSize = 0;
return NULL;
}
- ( 1 ) (1) (1) 对第一个数组进行递增排序;
- ( 2 ) (2) (2) 对第二个数组进行递增排序;
- ( 3 ) (3) (3) 对第一个数组求和;
- ( 4 ) (4) (4) 对第一个数组求和;
- ( 5 ) (5) (5) 2 ∗ x − s u m 1 + s u m 2 2*x - sum1 + sum2 2∗x−sum1+sum2 必须被 2 2 2 整除;
- ( 6 ) (6) (6) 根据 x x x 计算 y y y;
- ( 7 ) (7) (7) 返回 ( x , y ) (x, y) (x,y);
三、本题小知识
二分的问题,可以先把问题简单分析下,列出算式,逐渐抽象,抽丝剥茧,最后抽象成二分枚举问题求解。
以上是关于⭐算法入门⭐《二分枚举》中等01 —— LeetCode 面试题 16.21. 交换和的主要内容,如果未能解决你的问题,请参考以下文章
⭐算法入门⭐《二分枚举》中等02 —— LeetCode 面试题 10.09. 排序矩阵查找
⭐算法入门⭐《二分枚举》中等06 —— LeetCode 275. H 指数 II
⭐算法入门⭐《二分枚举》中等03 —— LeetCode 1539. 第 k 个缺失的正整数