-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
137 lines (121 loc) · 4.03 KB
/
main.cpp
File metadata and controls
137 lines (121 loc) · 4.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Source: https://leetcode.com/problems/can-make-arithmetic-progression-from-sequence
// Title: Can Make Arithmetic Progression From Sequence
// Difficulty: Easy
// Author: Mu Yang <http://muyang.pro>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// A sequence of numbers is called an **arithmetic progression** if the difference between any two consecutive elements is the same.
//
// Given an array of numbers `arr`, return `true` if the array can be rearranged to form an **arithmetic progression**. Otherwise, return `false`.
//
// **Example 1:**
//
// ```
// Input: arr = [3,5,1]
// Output: true
// Explanation: We can reorder the elements as [1,3,5] or [5,3,1] with differences 2 and -2 respectively, between each consecutive elements.
// ```
//
// **Example 2:**
//
// ```
// Input: arr = [1,2,4]
// Output: false
// Explanation: There is no way to reorder the elements to obtain an arithmetic progression.
// ```
//
// **Constraints:**
//
// - `2 <= arr.length <= 1000`
// - `-10^6 <= arr[i] <= 10^6`
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <algorithm>
#include <vector>
using namespace std;
// Sort
class Solution {
public:
bool canMakeArithmeticProgression(vector<int>& arr) {
// Trivial
const int n = arr.size();
if (n <= 2) return true;
// Sort
sort(arr.begin(), arr.end());
// Check
const int diff = arr[1] - arr[0];
for (int i = 2; i < n; ++i) {
if (arr[i] - arr[i - 1] != diff) return false;
}
return true;
}
};
// Array
//
// Find the maximum and the minimum number.
// The difference is equal to (max-min)/(n-1).
// Use an array of boolean to check if every term exists.
class Solution2 {
using Bool = unsigned char;
public:
bool canMakeArithmeticProgression(const vector<int>& arr) {
// Trivial
const int n = arr.size();
if (n <= 2) return true;
// Count
const auto [minIt, maxIt] = minmax_element(arr.cbegin(), arr.cend());
const int minVal = *minIt, maxVal = *maxIt;
const int range = maxVal - minVal;
if (range == 0) return true; // all equal
if (range % (n - 1) != 0) return false; // difference not integer
const int diff = range / (n - 1);
// Check
auto seen = vector<Bool>(n);
for (const auto num : arr) {
const int d = num - minVal;
if (d % diff != 0) return false; // invalid number
const int idx = d / diff;
if (seen[idx]) return false; // duplicated number
seen[idx] = true;
}
return true;
}
};
// Swap Sort
//
// Find the maximum and the minimum number.
// The difference is equal to (max-min)/(n-1).
// Assume that the array can be rearranged to arithmetic series.
// For each number in the array, we can compute its index in the sorted array.
//
// We start from the first slot and swap the number to its destination.
// Keep swapping until the current number is already at currect position.
// Next move on to the number slot until the array is sorted.
//
// This sort only cost O(n) since each swap will eliminate one unsorted number.
class Solution3 {
using Bool = unsigned char;
public:
bool canMakeArithmeticProgression(vector<int>& arr) {
// Trivial
const int n = arr.size();
if (n <= 2) return true;
// Count
const auto [minIt, maxIt] = minmax_element(arr.cbegin(), arr.cend());
const int minVal = *minIt, maxVal = *maxIt;
const int range = maxVal - minVal;
if (range == 0) return true; // all equal
if (range % (n - 1) != 0) return false; // difference not integer
const int diff = range / (n - 1);
// Sort
for (int i = 0; i < n; ++i) {
while (arr[i] != minVal + i * diff) {
const int d = arr[i] - minVal;
if (d % diff != 0) return false; // invalid number
const int dst = d / diff;
if (arr[i] == arr[dst]) return false; // duplicated number
swap(arr[i], arr[dst]);
}
}
return true;
}
};