Can someone help me interpret this C code? - c

This is another question (I posted one other one, go look!) from my computer science final study guide. I am not sure how to get the value of x[2] or x[5] without a computer (No computers used during the exam). Can someone please explain how to figure out these values just by reading the code? Thanks!
int x[SIZE] = {5, 3, 4, 5, 2, 4, 3, 5, 1, 2};
int i;
int j;
for(i = 0; i < SIZE / 2; i++)
{
for(j = x[i]; j < SIZE; j++)
{
x[j]++;
}
}
printf("x[2] = %d\n", x[2]);
printf("x[5] = %d\n", x[5]);

Firstly, the array is
int x[SIZE] = {5, 3, 4, 5, 2, 4, 3, 5, 1, 2};
and SIZE is 10 ( or I'll assume it is 10 ).
The outer for loop is
for(i = 0; i < SIZE / 2; i++)
so it iterates from i=0 to i=4.
Now, let's look at the inner for loop
for(j = x[i]; j < SIZE; j++)
{
x[j]++;
}
The value assigned for j is x[i].
Firstly, at i=0, the value of j would be x[0] which is 5. So, the inner for loop executes from j=5 to j=9. In the loop, it does x[j]++, that is, x[5]++, which is 4++, which gives 5. Now on the next iteration of the inner loop, j=6, and x[6]++, so 3++, hence gives 4. So, all the values of the array from x[5] to x[9] are incremented once.
So, the array now becomes
5 3 4 5 2 5 4 6 2 3
If you look at this pattern, you will notice that to for the value of x[2] to change, j must become 2 and for that x[i] must be 2, but looking at the the way the loop will progress, you can see that the values of x[0], x[1] and x[2] will not change. So, x[2] will remain as 4.
Now, moving on to the next iteration of the outer loop, i=1, so j=x[1], so from j=3 to j=9, increment the values of x[j], so the array becomes
5 3 4 6 3 6 5 7 3 4
For the next iteration at i=2, the inner loop iterates from j=4 to j=9, so the array becomes
5 3 4 6 4 7 6 8 4 5
For the next iteration at i=3, the inner loop iterates from j=6 to j=9, and hence the array becomes
5 3 4 6 4 7 7 9 5 6
And now, for the last iteration of the outer loop, at i=4 , the inner loop iterates from j=4 to j=9, and the array becomes
5 3 4 6 5 8 8 10 6 7
So, the output of the program would be
x[2] = 4
x[5] = 8
This is how to interpret programs like these without a compiler.

x is an array. An array has a group of elements in it. The elements are indexed by a number. In C the index starts from 0. So the first element has an index 0, second one's index is 1 and so on.
So if you are looking for x[2] that means the element at index 2 or position 3 which is 4 in the given code. But wait, there is a nested loop between the array definition and the printing of that value. This means that the original values in the array changes. So, you need to figure out what changes the loop makes to the array by manually iterating through it on a piece of paper. I'll leave that part to you.

Related

How do I access the memory using pointers for a multidimensional array?

I have been learning memory allocation and pointers lately, and I made this program which will ask the user to input the dimensions of a matrix and enter it's elements, after which it displays the elements in a matrix format. Here's the code that I've typed.
#include"stdio.h"
#include"stdlib.h"
int *minput();
int *minput(int x,int y)
{
int *M;
M=(int*)malloc(x*y*sizeof(int));
for(int i=0;i<=(x-1);i++)
{
for(int j=0;j<=(y-1);j++)
{
printf("A(%d,%d)=",i+1,j+1);
scanf("%d",(M+i+j));
}
}
return M;
}
int main()
{
int *A,a,b;
printf("Matrix is (m*n)\n\n");
printf("m=");
scanf("%d",&a);
printf("n=");
scanf("%d",&b);
A=minput(a,b);
printf("\n");
for(int k=0;k<=(a-1);k++)
{
for(int l=0;l<=(b-1);l++)
{
printf("%d ",*(A+k+l));
}
printf("\n");
}
free(A);
return 0;
}
However when I gave my inputs, I got this:
Matrix is (m*n)
m=3
n=3
A(1,1)=1
A(1,2)=2
A(1,3)=3
A(2,1)=4
A(2,2)=5
A(2,3)=6
A(3,1)=7
A(3,2)=8
A(3,3)=9
1 4 7
4 7 8
7 8 9
What's wrong? Amn't I supposed to get
1 2 3
4 5 6
7 8 9
Is there anything I had made wrong in my code?
You get incorrect output because *(A+k+l) is not the right way of accessing matrix element at matrix[k][l].
For addressing a matrix stored as a "flat" array you need to multiply the value of one of the indexes by the size of the opposite dimension. Depending on which index you multiply you get either a row-major order or a column-major order.
You need to apply the same fix to (M+i+j) inside minput function.
// Input
scanf("%d",(M+y*i+j));
...
// Output
printf("%d ",*(A+b*k+l));
The idea behind multiplying k by b is to make k "count faster". For each increment of k by 1 you need to skip an entire row of b elements. In your three-column matrix example, if you would like to access elements at A[k][0] (the initial column) of your matrix for each row, your index would count by three: 0, 3, 6. This is accomplished by multiplying k by b. The rest is the same as the usual pointer arithmetic: *(A+b*k+l) is equivalent to A[b*k+l].
Demo.
Lets take a close look at one of your loops (I use the input loop, but the error is in the output loop as well):
for(int i=0;i<=(x-1);i++)
{
for(int j=0;j<=(y-1);j++)
{
printf("A(%d,%d)=",i+1,j+1);
scanf("%d",(M+i+j));
}
}
The first iteration of the outer loop, i is zero. Then the inner loop runs, and we read into (in turn) M+0+0, M+0+1 and M+0+2.
Then we run the second iteration of the outer loop, where the inner loop will read into M+1+0, M+1+1 and M+1+2.
In these two iterations of the outer loop you will read into M+1 and M+2 twice. That's because M+0+1 and M+1+0 are the same element.
To fix this, lets take a look at your "matrix" as it is in memory
+---+---+---+---+---+---+---+---+---+
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
+---+---+---+---+---+---+---+---+---+
The numbers inside are the indexes. Now, 0, 1 and 2 is the first row. 3, 4 and 5 is the second. And 6, 7 and 8 is the last.
From this we can see that to get to the next line, we have to add the number of columns.
From this we get the formula line * number_of_columns + column to get the index.
Putting it in place, your input loop could look like
for(int i=0;i<x;i++)
{
for(int j=0;j<y;j++)
{
printf("A(%d,%d)=",i+1,j+1);
scanf("%d",M+i*y+j);
}
}
To choose the address in which to write a value, you use:
M+i+j
Let's try that for a few values of (i,j):
0,0 -> M + 0
0,1 -> M + 1
0,2 -> M + 2 // So far so good.
1,0 -> M + 1 // not right
1,1 -> M + 2 // not right
... etc.
You want M + (i * x) + j. For x == 3:
0,0 -> M + 0
0,1 -> M + 1
0,2 -> M + 2
1,0 -> M + 3
1,1 -> M + 4
... etc.
The same goes for the pointer arithmetic when reading from the same memory.
Furthermore, since the pointer just goes up by one each time, you could get the same behaviour with:
int *m = M;
for(int i=0;i<x;i++)
{
for(int j=0;j<=(y-1);j++)
{
printf("A(%d,%d)=",i+1,j+1);
scanf("%d",m);
m++;
}
}
Or even:
for(int i=0; i<x*y; i++) {
printf("A(%d,%d)=", i/3, i%3);
scanf("%d", M + i);
}
Other points:
In one method you use variables x,y,i,j, and in another you use a,b,k,l. I assume you've done this because you don't want to overwrite one with the other. But because of scope, that's not a factor. x is local to the function minput() -- you can have another x in main() and they will be completely independent of one another. Use x,y,i,j in both places, because they are the "sensible" names for dimensions and loop counters.
for(i=0; i<x; i++) is the conventional way of looping x times. Your i<=(x-1) is equivalent but messy and confusing.
Casting the result of malloc() is discouraged nowadays. Do I cast the result of malloc?
int *M = malloc(x*y*sizeof(int));

What is this trying to tell me?

I am reading the book "How to solve it by computer" by RG Dromey. I am stuck on a sentence that is trying to explain termination of loops. Here goes the problem:
Suppose we wish to establish that an array of n elements is in strictly ascending order (i.e. a[1] < a[2] < ... < a[n]) . To do this we can use the following instructions:
a[n+1] := a[n];
i := 1;
while a[i] < a[i+1] do i := i+1
(Now if n is the number of elements, what does i stand for in this case? Does it stand for values?)
If n was assigned the value 5 and the data set was 2, 3, 5, 11, 14, then the first assignment prior to the loop would result in the array configuration below:
(This is where I get confused.)
a[1] a[2] a[3] a[4] a[5] a[6]
2 3 5 11 14 14
The two 14's guarantee that the test a[i] < a[i+1] will be false when i = n and so the loop will terminate correctly when i = n if not before.
(This is confusing.)
i is simply the index
i := 1; means i is equal 1
i := i+1 means add 1 to i
n = 5
a[5] = 14
a[5+1] = a[6] = 14
14 < 14 is false - the loop terminates

Finding max occurence of element, array syntax [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
The following code is an algorithm for searching for the maximum occurrence of an element in an array. This solution assumes that an element ranges from 0 to n-1.
void MaxRepetitions( int A[], int n ) {
int i=0; max=0, maxIndex;
for(i=0, i<n, i++)
A[A[i]%n] +=n;
for( i=0, i<n, i++)
if (A[i]/n > max) {
max = A[i]/n;
maxIndex=i;
}
return maxIndex;
}
How is A[A[i]%n] +=n; expanded?
Is A[A[i]%n] = A[A[i]%n] + n correct?
--
Edit
For the example where A = [2, 4, 7, 5, 4, 11], where n=6
A[0]%n = 2
A[1]%n = 4
A[2]%n = 1
A[3]%n = 5
A[4]%n = 4
A[5]%n = 5
After this loop:
for(i=0, i<n, i++)
A[A[i]%n] = A[A[i]%n] + n;
Iteration 1:
A[A[0]%n] = A[A[0]%n] + 6 --> A[2] = A[2] + 6 --> A[2] = 13
The array is now: A = [2, 4, 13, 5, 4, 11]
Iteration 2:
A[A[1]%n] = A[A[1]%n] + 6 --> A[4] = A[4] + 6 --> A[4] = 10
The array is now: A = [2, 4, 13, 5, 10, 11]
Iteration 3:
A[A[2]%n] = A[A[2]%n] + 6 --> A[1] = A[1] + 6 --> A[1] = 10
The array is now: A = [2, 10, 13, 5, 10, 11]
Iteration 4:
A[A[3]%n] = A[A[3]%n] + 6 --> A[5] = A[5] + 6 --> A[5] = 17
The array is now: A = [2, 10, 13, 5, 10, 17]
Iteration 5:
A[4] now is 10
A[A[4]%n] = A[A[4]%n] + 6 --> A[4] = A[4] + 6 --> A[4] = 16
The array is now: A = [2, 10, 13, 5, 16, 17]
Iteration 6:
A[5] now is 17
A[A[5]%n] = A[A[5]%n] + 6 --> A[5] = A[5] + 6 --> A[5] = 23
The array is now: A = [2, 10, 13, 5, 16, 23]
Now, once the second loop runs, A[i]/n for each of the elements is: A [0, 1, 2, 0, 2, 3 ]
It looks like this algorithm will choose 11 as the element with most occurrences which isn't true. Any help?
As others have said, <anything> += <value> is equivalent to <anything> = <anything> + <value> except that <anything> is evaluated only once.
Your analysis of the running of the algorithm is correct, but the problem is that the input violates the stated constraint that all elements are between 0 and n-1. In effect, since 11 % 6 = 5, the answer produced by the algorithm isn't completely wrong (modulo 6, the value 5 occurs the same number of times as the value 4). However, there is a further problem in that because the input constraint is violated, the counts are off for reasons that I explain in a comment below.
The best way to understand how this works is to look at another algorithm which, while seemingly quite different, is actually the same thing. This other algorithm is:
Allocate a separate array C[n]. (C for "count".)
Loop through each element A[i] of A and set C[A[i]] += 1. It's not too hard to see that, since each A[i] is between 0 and n-1, when this step finishes, C[j] for any j will be the number of times that the value j occurs among all the A[i].
Thus, the position of the largest element of C is the most frequently occurring value in A (with ties being resolved arbitrarily). Simply loop through C to find where this occurs and return the result.
Now the algorithm you posted is exactly that, but cleverly making use of two facts, both of which rely on the original values of A[i] being between 0 and n-1:
The value of A[i]%n will be exactly equal to the original value of A[i] regardless of how many times n has been added to A[i].
The value of A[i]/n will be exactly equal to the number of times n has been added to A[i], regardless of the original value of A[i].
So if we modify the second algorithm by adding n instead of 1, and by using %n and /n as is done in your posted algorithm, we can make A serve for both holding the original values and for holding the counts.
This:
A[A[i]%n] +=n
Is expanded to be equivalent to this:
A[A[i]%n] = A[A[i]%n] + n
Except that side-effects are only evaluated once. In other words, if the left expression had employed operators with side-effects like ++ and --, then these side-effects would only occur once, contrary to what had happened if you had actually written out the whole x = x + y expression, where side-effects in x would be evaluated twice.
A[A[i]%n] +=n
A[i] : value contained in array A at position i
A[i]%n : remainder of dividing this value by n (used to not allow this index go beyond the size of A
A[A[i]%n] : the value contained in that new position
A[A[i]%n] += n : add n to this value
Numerical example :
A[3] = {7, 10, 24}
n = 3
i = 0
A[A[0]%3] = A[7%3] // 7 = 2*3 + 1
= A[1]
= 10
add 3 ==> A[1] = 13
i = 1
A[A[1]%3] = A[13%3] // 13 = 4*3 +1
= A[1]
= 13
add 3 ==> A[1] = 16
i = 2
A[A[2]%3] = A[24%3] // 24 = 8*3 + 0
= A[1]
= 7
add 3 ==> A[1] = 10

how to code a for loop using a 2 dimensional array

I am just learning java and while completing an assignment i ran into a problem. I need to use the for loop but I'm unsure of the proper coding. I was able to compile my code to get the output for the 1st challenge but i am unable to do so for the remaining challenges. Any suggestions/tips are greatly appreciated.
/Your instructor is in a bind. His place of work has instituted a new
//technology project that will require remote access verification.
//In addition to his user name and password, he will have a “challenge”
//to each sign-on. That challenge will require that he input a number or
//letter depending on what the security application asks him.
//But your instructor is lazy. He wants an application that will
//tell him what those appropriate numbers are without him having to
//look them up each time. He understands that this will help foil
//remote hackers, but he does not want to be stuck carrying around a piece of paper all the time.
//Write your instructor a program that gives him the three characters asked for. The matrix to use is:
//A B C D E F G H I J
//1 3 N 1 M 4 R X 5 F N
//2 N V T 5 K Q F M 3 P
//3 9 K 1 Y R 4 V T F 3
//4 3 3 9 V 4 Y R T N N
//5 3 1 1 3 2 9 X P N P
//A challenge of A1:B2:C3 would yield 3 V 1.
//A challenge of G4:D2:J3 would yield R 5 3.
// 1. Create a place to accept input
// ---- create a scanner class
// 2. ask for input
String input = "a1";
// 3. Take the first character from the challenge
// (like "D2" would "D" and find its analogous int array value)
int i1 = Util.findFirstValue(input);
System.out.println(i1);
// 4.Take the second character from the challenge (like "D2"
// would be "2") and find its analogous int array value
// Hint: always one less than the value entered.
int i2 = Util.findSecondValue(input);
System.out.println(i2);
// 5. inquire with the array with the challenge values to get the desired value
System.out.println(Util.findArrayValue(i1, i2));
// 6. display the value
// 7. repeat twice more steps 2 through 6
}
{
for (int row =1; row<9;row ++) {
for (int column =2; column <5;column ++) {
For looping through multi dimensional arrays it must like this
for(int i=0; i<multiarray[i].length; i++) {
multiarray[i][k]; //do something with it!
}
You can find heree about iterating multi dimensiona array in java.
Think of a 2D array like a table. The first for loop to get a row from that table, then the next for loop gets a certain element from that row (column).
1, 2, 3
4, 5, 6 --> 4, 5, 6 --> 6
7, 8, 9 array[1] array[1][2]
So basically. The first loop gets the basic array within the 2D array, the next gets that exact value in that basic array.
Code:
int[][] A = { {1,2,3},
{4,5,6},
{7,8,9} };
for(int i = 0; A.length>i; i++) {
for(int j = 0; A[0].length>j; j++) {
System.out.println(A[i][j]);
}
}
Output:
1
2
3
4
5
6
7
8
9

Find pairs that sum to X in an array of integers of size N having element in the range 0 to N-1

It is an interview question. We have an array of integers of size N containing element between 0 to N-1. It may be possible that a number can occur more than two times. The goal is to find pairs that sum to a given number X.
I did it using an auxiliary array having count of elements of primary array and then rearranging primary according auxiliary array so that primary is sorted and then searched for pairs.
But interviewer wanted space complexity constant, so I told him to sort the array but it is nlogn time complexity solution. He wanted O(n) solution.
Is there any method available to do it in O(n) without any extra space?
No, I don't believe so. You either need extra space to be able to "sort" the data in O(n) by assigning to buckets, or you need to sort in-place which will not be O(n).
Of course, there are always tricks if you can make certain assumptions. For example, if N < 64K and your integers are 32 bits wide, you can multiplex the space required for the count array on top of the current array.
In other words, use the lower 16 bits for storing the values in the array and then use the upper 16 bits for your array where you simply store the count of values matching the index.
Let's use a simplified example where N == 8. Hence the array is 8 elements in length and the integers at each element are less than 8, though they're eight bits wide. That means (initially) the top four bits of each element are zero.
0 1 2 3 4 5 6 7 <- index
(0)7 (0)6 (0)2 (0)5 (0)3 (0)3 (0)7 (0)7
The pseudo-code for an O(n) adjustment which stores the count into the upper four bits is:
for idx = 0 to N:
array[array[idx] % 16] += 16 // add 1 to top four bits
By way of example, consider the first index which stores 7. That assignment statement will therefore add 16 to index 7, upping the count of sevens. The modulo operator is to ensure that values which have already been increased only use the lower four bits to specify the array index.
So the array eventually becomes:
0 1 2 3 4 5 6 7 <- index
(0)7 (0)6 (1)2 (2)5 (0)3 (1)3 (1)7 (3)7
Then you have your new array in constant space and you can just use int (array[X] / 16) to get the count of how many X values there were.
But, that's pretty devious and requires certain assumptions as mentioned before. It may well be that level of deviousness the interviewer was looking for, or they may just want to see how a prospective employee handle the Kobayashi Maru of coding :-)
Once you have the counts, it's a simple matter to find pairs that sum to a given X, still in O(N). The basic approach would be to get the cartestian product. For example, again consider that N is 8 and you want pairs that sum to 8. Ignore the lower half of the multiplexed array above (since you're only interested in the counts, you have:
0 1 2 3 4 5 6 7 <- index
(0) (0) (1) (2) (0) (1) (1) (3)
What you basically do is step through the array one by one getting the product of the counts of numbers that sum to 8.
For 0, you would need to add 8 (which doesn't exist).
For 1, you need to add 7. The product of the counts is 0 x 3, so that gives nothing.
For 2, you need to add 6. The product of the counts is 1 x 1, so that gives one occurrence of (2,6).
For 3, you need to add 5. The product of the counts is 2 x 1, so that gives two occurrences of (3,5).
For 4, it's a special case since you can't use the product. In this case it doesn't matter since there are no 4s but, if there was one, that couldn't become a pair. Where the numbers you're pairing are the same, the formula is (assuming there are m of them) 1 + 2 + 3 + ... + m-1. With a bit of mathematical widardry, that turns out to be m(m-1)/2.
Beyond that, you're pairing with values to the left, which you've already done so you stop.
So what you have ended up with from
a b c d e f g h <- identifiers
7 6 2 5 3 3 7 7
is:
(2,6) (3,5) (3,5)
(c,b) (e,d) (f,d) <- identifiers
No other values add up to 8.
The following program illustrates this in operation:
#include <stdio.h>
int arr[] = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 4, 4, 4, 4};
#define SZ (sizeof(arr) / sizeof(*arr))
static void dumpArr (char *desc) {
int i;
printf ("%s:\n Indexes:", desc);
for (i = 0; i < SZ; i++) printf (" %2d", i);
printf ("\n Counts :");
for (i = 0; i < SZ; i++) printf (" %2d", arr[i] / 100);
printf ("\n Values :");
for (i = 0; i < SZ; i++) printf (" %2d", arr[i] % 100);
puts ("\n=====\n");
}
That bit above is just for debugging. The actual code to do the bucket sort is below:
int main (void) {
int i, j, find, prod;
dumpArr ("Initial");
// Sort array in O(1) - bucket sort.
for (i = 0; i < SZ; i++) {
arr[arr[i] % 100] += 100;
}
And we finish with the code to do the pairings:
dumpArr ("After bucket sort");
// Now do pairings.
find = 8;
for (i = 0, j = find - i; i <= j; i++, j--) {
if (i == j) {
prod = (arr[i]/100) * (arr[i]/100-1) / 2;
if (prod > 0) {
printf ("(%d,%d) %d time(s)\n", i, j, prod);
}
} else {
if ((j >= 0) && (j < SZ)) {
prod = (arr[i]/100) * (arr[j]/100);
if (prod > 0) {
printf ("(%d,%d) %d time(s)\n", i, j, prod);
}
}
}
}
return 0;
}
The output is:
Initial:
Indexes: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Counts : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Values : 3 1 4 1 5 9 2 6 5 3 5 8 9 4 4 4 4
=====
After bucket sort:
Indexes: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Counts : 0 2 1 2 5 3 1 0 1 2 0 0 0 0 0 0 0
Values : 3 1 4 1 5 9 2 6 5 3 5 8 9 4 4 4 4
=====
(2,6) 1 time(s)
(3,5) 6 time(s)
(4,4) 10 time(s)
and, if you examine the input digits, you'll find the pairs are correct.
This may be done by converting the input array to the list of counters "in-place" in O(N) time. Of course this assumes input array is not immutable. There is no need for any additional assumptions about unused bits in each array element.
Start with the following pre-processing: try to move each array's element to the position determined by element's value; move element on this position also to the position determined by its value; continue until:
next element is moved to the position from where this cycle was started,
next element cannot be moved because it is already on the position corresponding to its value (in this case put current element to the position from where this cycle was started).
After pre-processing every element either is located at its "proper" position or "points" to its "proper" position. In case we have an unused bit in each element, we could convert each properly positioned element into a counter, initialize it with "1", and allow each "pointing" element to increase appropriate counter. Additional bit allows to distinguish counters from values. The same thing may be done without any additional bits but with less trivial algorithm.
Count how may values in the array are equal to 0 or 1. If there are any such values, reset them to zero and update counters at positions 0 and/or 1. Set k=2 (size of the array's part that has values less than k replaced by counters). Apply the following procedure for k = 2, 4, 8, ...
Find elements at positions k .. 2k-1 which are at their "proper" position, replace them with counters, initial value is "1".
For any element at positions k .. 2k-1 with values 2 .. k-1 update corresponding counter at positions 2 .. k-1 and reset value to zero.
For any element at positions 0 .. 2k-1 with values k .. 2k-1 update corresponding counter at positions k .. 2k-1 and reset value to zero.
All iterations of this procedure together have O(N) time complexity. At the end the input array is completely converted to the array of counters. The only difficulty here is that up to two counters at positions 0 .. 2k-1 may have values greater than k-1. But this could be mitigated by storing two additional indexes for each of them and processing elements at these indexes as counters instead of values.
After an array of counters is produced, we could just multiply pairs of counters (where corresponding pair of indexes sum to X) to get the required counts of pairs.
String sorting is n log n however if you can assume the numbers are bounded (and you can because you're only interested in numbers that sum to a certain value) you can use a Radix sort. Radix sort takes O(kN) time, where "k" is the length of the key. That's a constant in your case, so I think it's fair to say O(N).
Generally I would however solve this using a hash e.g.
http://41j.com/blog/2012/04/find-items-in-an-array-that-sum-to-15/
Though that is of course not a linear time solution.

Resources