题目及要求
14 检查整数及其两倍数是否存在
作者: Turbo时间限制: 1S章节: 课程设计
问题描述 :
给你一个整数数组 arr,请你检查是否存在两个整数 N 和 M,满足 N 是 M 的两倍(即,N == 2 * M)。
更正式地,检查是否存在两个下标 i 和 j 满足:
i != j
0 <= i, j < arr.length
arr[i] == 2 * arr[j]
示例 1:
输入:
4
10 2 5 3
输出:true
解释:N = 10 是 M = 5 的两倍,即 10 = 2 * 5 。
示例 2:
输入:
4
7 1 14 11
输出:true
解释:N = 14 是 M = 7 的两倍,即 14 = 2 * 7 。
示例 3:
输入:
4
3 1 7 11
输出:false
解释:在该情况下不存在 N 和 M 满足 N = 2 * M 。
输入说明 :
输入两行:
第一行输入一个整数n表示数组arr的长度。
第二行输入n个整数表示数组的元素。
提示:
2 <= n <= 500
-10^3 <= arr[i] <= 10^3
输出说明 :
输出一个布尔值true或false表示结果。
设计与分析
概要设计
unordered_map<int, int > h;
for (int i = 0; i < n; i++) {
//h.emplace(make_pair(arr.at(i), 1));
h[arr.at(i)]++;//second对应那个first的数目
}
bool flag = dou(h, arr);
if (flag)
cout << "true";
else
cout << "false";
首先在main函数中使用unordered_map<int,int>哈希表,并且用每一个first对应的second来表示这个first的出现次数,然后在函数中
bool dou(unordered_map<int, int> h, vector<int> arr) {
for (auto item : arr) {
if (item == 0&&h[0]>1) {//如果数组中有两个以上的0那就返回true
return true;
}
if (item != 0 && (h.find(2 * item) != h.end() || (item % 2 == 0 && h.find(item / 2) != h.end())))
return true;
}
return false;
}
通过对于这个数组内元素以及每个元素出现次数的判断分析,来决定是输出true还是false。
函数主要思想:
对于数组内部元素首先分为0和非0
如果是0则判断0的个数有多少,如果是两个及其以上,那么满足条件返回true
如果非0,则判断first是此数乘以2时其对应的second还有first是该数除以二时对应的second是否存在,是则返回true。
算法分析
我一开始的代码
#define ll long long
class cmp{
public:
bool operator()(int a,int b){
return a>b;
}
};
int main(){
int n;
cin>>n;
multiset<int> h;
for(int i=0;i<n;i++){
int k;
cin>>k;
h.insert(k);
}
bool flag= false;
if(n>1) {
for (auto item: h) {
if (item > 2 * item) {
for (auto itm: h) {
if (itm == 2 * item) {
flag = 1;
cout << "true";
break;
}
}
if(flag)
break;
} else if (item == 2 * item) {
flag = 1;
cout << "true";
break;
} else if (item < 2 * item) {
for (auto itm: h) {
if (itm == item * 2) {
flag = 1;
cout << "true";
break;
}
}
if(flag)
break;
}
}
if (flag == 0)
cout << "false";
}
else cout<<"false";
return 0;
}
改进之后的代码:哈希表法6
#include "bits/stdc++.h"
#include<unordered_map>
using namespace std;
bool dou(unordered_map<int, int> h, vector<int> arr) {
for (auto item : arr) {
if (item == 0&&h[0]>1) {//如果数组中有两个以上的0那就返回true
return true;
}
if (item != 0 && (h.find(2 * item) != h.end() || (item % 2 == 0 && h.find(item / 2) != h.end())))
return true;
}
return false;
}
int main() {
int n;
cin >> n;
vector<int> arr;
for (int i = 0; i < n; i++) {
int a;
cin >> a;
arr.emplace_back(a);
}
unordered_map<int, int > h;
for (int i = 0; i < n; i++) {
//h.emplace(make_pair(arr.at(i), 1));
h[arr.at(i)]++;//second对应那个first的数目
}
bool flag = dou(h, arr);
if (flag)
cout << "true";
else
cout << "false";
return 0;
}
算法时间复杂度为O(n),在关键函数中需要将数组中的所有元素从头至尾的遍历一遍
使用与分析
使用说明
测试结果与分析
1.测试全为正数且不成立的
输入:
5
1 3 5 7 9
输出:
false
2. 测试全为正数且成立的
输入:
8
1 2 4 5 7 11 13 15
输出:
true
3. 测试全为负数且不成立的
输入:
7
-1 -3 -5 -7 -9 -11
输出:
false
4.测试全为负数且成立
输入:
6
-1 -2 -3 -5 -6 -8
输出:
true
5. 测试有正有负且不成立
输入:
4
-3 -1 1 5
输出:
false
6. 测试有正有负且成立
输入:
10
-4 -2 -1 -5 -11 1 5 8 6 4
输出:
true
7测试
输入:有正有负有一个零 且成立
6
-3 -2 -1 0 5 8
输出:
true
8. 测试有正有负有一个零且不成立
输入:
6
-3 -1 0 1 15 51
输出:
false
9. 测试有正有负有两个零
输入:
13
-3 -2 -9 -5 -7 0 0 15 31 63 72 28 16
输出:
true
10. 测试
输入:
15
-5 -96 -12 -52 -15 0 13 15 14 16 92 17 35 -42 -45
输出:
false