Solution to the 273rd weekly game of Leetcode (C + + version)
Problem A - Number reversed twice
meaning of the title
Ask whether a number reversed twice is equal to the original number
thinking
Only the last 0 matches the number 0
code
class Solution { public: bool isSameAfterReversals(int num) { return (num%10||num==0); } };
Problem B - Execute all suffix instructions
meaning of the title
Given an n*n grid graph, a starting point and a moving sequence, how many steps can be moved within the grid for each suffix of the sequence?
thinking
We note that both the length m of the moving sequence and the size n of the graph are
[
1
,
500
]
[1,500]
[1500], then directly simulate each suffix.
code
class Solution { public: int sol(int n, vector<int>& startPos, string s){ int x=startPos[0],y=startPos[1]; int m=s.size(); for(int i=0;i<m;i++){ if(s[i]=='L') y--; if(s[i]=='R') y++; if(s[i]=='U') x--; if(s[i]=='D') x++; if(x<0||y<0||x>=n||y>=n) return i; } return m; } vector<int> executeInstructions(int n, vector<int>& startPos, string s) { int m=s.size(); vector<int> ans; vector<string> str(m); for(int i=0;i<m;i++) str[i]=s[m-1-i]+(i?str[i-1]:""); for(int i=m-1;i>=0;i--) ans.push_back(sol(n,startPos,str[i])); return ans; } };
Problem C - Sum of intervals of the same elements
meaning of the title
Given an array, for each element, find the sum of the distances from the element to all other elements in the array with its equivalent.
thinking
For each value in the array, record the sum of all subscripts and the total number of occurrences of each value; So for each position now, the answer ans[now] is
a
n
s
[
n
o
w
]
=
∑
(
i
=
0
)
&
&
(
a
r
r
[
i
]
=
=
a
r
r
[
n
o
w
]
)
n
∣
i
−
n
o
w
∣
ans[now]=\sum_{(i=0) \&\& (arr[i]==arr[now])}^{n}{|i-now|}
ans[now]=(i=0)&&(arr[i]==arr[now])∑n∣i−now∣
Obviously, we can divide the answer into two cases: on the left side of now and on the right side of now, which can be simplified as:
a
n
s
[
n
o
w
]
=
(
When
front
value
already
meter
count
number
amount
(
Left
side
)
−
not
meter
count
number
amount
(
right
side
)
)
∗
n
o
w
+
(
(
total
lower
mark
and
−
n
o
w
)
(
right
side
)
−
already
meter
count
of
lower
mark
and
(
Left
side
)
)
ans[now] = (current value calculated quantity (left) - uncalculated quantity (right)) * now \ \ + ((total subscript sum - now) (right) - calculated subscript sum (left))
ans[now] = (current value calculated quantity (left) − uncalculated quantity (right)) * now + ((total subscript and − now) (right) − calculated subscript and (left))
From the simplified formula, we can see that we need to record how many numbers with the value of arr[now] have been calculated and the total subscript of the value of arr[now]. We can think of using the prefix sum to record the value, that is, using the array cnt2 to record how many times the value of arr[now] has appeared at the current position, Array sum2 records the sum of subscripts of all elements whose values are equal to arr[now] at the current position. At the same time, array sum records the sum of all subscripts of the current value, and cnt records the total number of occurrences of the current value, which is expressed in code, that is:
a
n
s
[
n
o
w
]
=
(
c
n
t
2
[
a
r
r
[
n
o
w
]
]
−
(
c
n
t
[
a
r
r
[
n
o
w
]
]
−
1
−
c
n
t
2
[
a
r
r
[
n
o
w
]
]
)
)
∗
n
o
w
+
(
(
s
u
m
[
a
r
r
[
n
o
w
]
]
−
s
u
m
2
[
a
r
r
[
n
o
w
]
]
−
n
o
w
)
−
s
u
m
2
[
a
r
r
[
i
]
]
)
)
ans[now]= (cnt2[arr[now]]-(cnt[arr[now]]-1-cnt2[arr[now]]))*now\\ +((sum[arr[now]]-sum2[arr[now]]-now)-sum2[arr[i]]))
ans[now]=(cnt2[arr[now]]−(cnt[arr[now]]−1−cnt2[arr[now]]))∗now+((sum[arr[now]]−sum2[arr[now]]−now)−sum2[arr[i]]))
code
class Solution { public: vector<long long> getDistances(vector<int>& arr) { long long sum[100005]={0},sum2[100005],cnt[100005],cnt2[100006]; vector<long long> ans; int n=arr.size(); for(int i=0;i<n;i++){ sum[arr[i]]=0;//Sum of subscripts for each value sum2[arr[i]]=0;//Prefix of the currently calculated subscript sum cnt[arr[i]]=0;//Number of occurrences per value cnt2[arr[i]]=0;//Calculated number of subscripts per value } for(int i=0;i<n;i++){ cnt[arr[i]]++; sum[arr[i]]+=i; } for(int i=0;i<n;i++){ int m=cnt[arr[i]]; //cout<<cnt[arr[i]]<<' '<<(m-1-cnt[arr[i]])<<' '<<sum[arr[i]]-sum2[arr[i]]-i<<' '<<sum2[arr[i]]<<endl; ans.push_back( (cnt2[arr[i]]/*left*/-(m-1-cnt2[arr[i]])/*right*/)*i+((sum[arr[i]]-sum2[arr[i]]-i)/*right*/-sum2[arr[i]]/*left*/)); sum2[arr[i]]+=i; cnt2[arr[i]]++; //cout<<i<<' '<<arr[i]<<' '<<ans[i]<<endl; } return ans; } };
Problem D - Restore original array
meaning of the title
The original three arrays are arr, lower and higher.
Satisfied with each
0
≤
i
<
n
0 \le i < n
Subscript i of 0 ≤ I < n, lower[i] = arr[i] - k
Satisfied with each
0
≤
i
<
n
0 \le i < n
Subscript i of 0 ≤ I < n, higher[i] = arr[i] + k
The above k is a positive integer
Now mix lower and higher together to disrupt (called nums array) and let you restore the arr array (ensure that there are answers)
1
≤
n
≤
1000
1 \le n \le 1000
1≤n≤1000
1
≤
n
u
m
s
[
i
]
≤
1
0
9
1 \le nums[i] \le 10^9
1≤nums[i]≤109
thinking
At first, I thought of enumerating K in a double loop. For each k, I use multiset to store and query whether there are n number pairs that meet the conditions, find one and delete one, so as to ensure that each number will be swept only once. At this time, the theoretical complexity is still high O ( n 3 ) O(n^3) O(n3).
However, we note that since there are guaranteed answers, an arr element corresponds to two num elements, that is, we need to pair the elements in num in pairs. Obviously, we can select num [0] fixedly, enumerate another element paired with it, and calculate it at the same time K K K. Calculated K K After K, use this in reverse K K K is paired in pairs, and so is the process O ( n ) O(n) O(n), so finally we can O ( n 2 ) O(n^2) The problem is solved within the time complexity of O(n2).
code
class Solution { public: vector<int> recoverArray(vector<int>& nums) { multiset<int> se; for(auto i:nums) se.insert(i); int n=nums.size(); for(int i=1;i<n;i++){ if((nums[0]+nums[i])%2==0){ int k=abs(nums[0]-nums[i])/2; if(k<=0) continue; vector<int> tmp; multiset<int> s1=se; while(!s1.empty()){ auto a=s1.begin(); auto b=s1.find(*a+2*k); if(b!=s1.end()){ tmp.push_back(*a+k); s1.erase(a); s1.erase(b); } else break; } if(tmp.size()==n/2) return tmp; } } vector<int> ans;//Will not come to this step return ans; } };