Reputation: 171
Explanation:
I've following problem statement at hand, I came across an interesting 2 liner, C solution for it under leedcode discussion section. I tried to decompose it to understand what it means, and except one small line, I understood the rest. My question is at the end.
Leetcode Problem Statement:
Given an array arr of positive integers sorted in a strictly increasing order, and an integer k. Find the kth positive integer that is missing from this array.
Example 1: Input: arr = [2,3,4,7,11], k = 5 Output: 9
Explanation: The missing positive integers are [1,5,6,8,9,10,12,13,...]. The 5th missing >>positive integer is 9.
Example 2: Input: arr = [1,2,3,4], k = 2 Output: 6
Explanation: The missing positive integers are [5,6,7,...]. The 2nd missing positive integer is 6.
Constraints:
arr[i] < arr[j]
for 1 <= i < j <= arr.length
Two liner C solution:
int findKthPositive(int* arr, int arrSize, int k){
for (int arrCurrIndex = 0, counter = 1 ; (k && (arrCurrIndex < arrSize) ? ((arr[arrCurrIndex] != counter) ? k-- : ++arrCurrIndex) : k--) || (k = counter-1, 0) ; counter++);
return k;
}
For reference: Following is a similar algorithm that's being deployed, but its just cleaner to understand.
int findKthPositive(int* arr, int arrSize, int k){
for (int counter=1, arrCurrIndex=0; counter<10000; counter++) {
// exceed arr limits
if (arrCurrIndex < arrSize) {
if (counter == arr[arrCurrIndex]) { // found element in array
index++;
continue;
}
}
// missing element
k--;
if (k==0) {
return counter;
}
}
return 0;
}
My question:
What does following line in solution #1 means exactly?
(k = counter-1, 0)
======UPDATE ON ANSWER=======
I modified solution #1 in question slightly to make it more readable. It highlights what is going on with the given statement in question. Here is the modified solution:
int findKthPositive(int* arr, int arrSize, int k){
// move counter out of the foor loop
int counter=1;
for (int arrCurrIndex = 0;
(k && (arrCurrIndex < arrSize) ?
((arr[arrCurrIndex] != counter) ? k-- : ++arrCurrIndex)
: k--); counter++);
return counter-1;
}
Upvotes: 2
Views: 111
Reputation: 7490
The binary comma operator ,
evaluates the first operand, discards the result and then evaluates the second one.
In the expression you posted we have
... || (k = counter-1, 0) ;
so counter-1
is actually assigned to k
but its evaluation (k
itself) is discarded so that 0
is used. Why 0? Because it is the neutral operand for logic or operator ||
. In fact
X || 0 ==> X
In other words we have the expression
stuff_at_the_left || (k = counter-1, 0 )
that is evaluated as
stuff_at_the_left || 0
And since 0 is the neutral operand in logical or, the final evaluation is stuff_at_the_left
.
The purpose of this weird expression is to cheat: the author at some point needed to assign that value to k
but without adding more lines "ruining" the one liner. So they included the assignment in the logical expression making it neutral with comma operator combined with or operator's neutral operand.
We also have to say that the assignment k=counter-1, 0
is performed only if all stuff_at_the_left
is evaluated as 0 (due to the short circuiting nature of logical operators in C). The resulting expanded code is
if (!stuff_at_the_left)
k= counter-1;
Note: the comma operator has the lowest precedence among all the operators in C, and that's why the assignment is performed at first.
Upvotes: 2