The question :
As i understand, the loop works like this :
k = 1
while true
{
if k <= N
{
if X == A(k)
exit loop
else
k = k + 1
}
else
exit loop
}
with the initial value is 1 and increment is 1, the loop will end if x = A(k)
So why is the given answer is A :
If the same value as Xexists in two places ofthe array, the 1st and
N-th elements, kis set to 1
I don't get it !
If the first element of the array equals X, then the loop is left before k is incremented – so it keeps the value it was initialized with, which is 1.
Related
I did a quiz about loops on R, and here are my answers to the questions: they are all incorrect and I would like to know why, if someone could explain to me. Thanks a lot.
1/ Write code that loops over a hypothetical vector var. If it encounters an NA, store the
sum of the previous and the subsequent value in the variable y. You can assume that
neither the first nor the last element of the vector will be NA.
for (i in 1: length (var)) {
if (is.na (var[i])) {
var[i] <- 0
}
y <- y + var[i]
2/ Write code that loops over each row of a hypothetical matrix M, calculates the minimum value of all values inside that row and appends the result to a vector vn. The vector
un should thus be as long as the number of rows of M.
y <- NULL
for(i in 1: nrow (M)) {
vn <- c(vn, min (M[i, ]))
}
3/ Write a while loop that adds i ^2 (the current iteration i at the power of 2) to a counter z. As soon as z is larger or equal than 7152, stop the while loop.
i=1
while (z>= 7152) {
z <- z + i^2
i<-i+1 }
4/ Write code that sets a variable isPrime to TRUE if some number y is a prime
number, and to FALSE if it is not. Tip: loop over all values 2, 3, 4, ..., y and check if y
is divisible by that value. If it is, set isPrime and use break to exit the loop. If your
loop reaches y, you know that is is a prime number. A second tip: take special care
that your code also works in case y happens to be 2.
if (y > 1) { isPrime = TRUE
for (i in 2: (y - 1)) {
if ((y %% i) == 0) {
if ((y %% 2) == 0){ isPrime = FALSE
break
} }
}
}
How I could determine the number of elements from an array in Matlab, without using functions such as length(), size(), etc. ?
Thanks you !
The logic is to iterate over the cells until an empty cell is encountered. I have taken two variables for iteration namely, i and j. i is for rows and j is for columns.
Initially set the value of i and j as i=1 and j=1. Now in a while loop iterate by incrementing j and keeping i = 1 as constant.
** First try to copy that cell in a variable x. If that cell is an empty cell an error will pop up. Aim is to take advantage of this error using try/catch statements.
Scince the statement x = vec(i,j); is written in the try block so on encountering an empty cell instead of try the catch block will be executed where flag = 0 makes the flag 0, this will cause the while loop to end.
So, we have the number of columns stored in j and the while loop terminates on encountering an empty cell.
flag = 1;
i = 1;
j = 1;
while(flag==1) % loop will continue till flag is 1 (or say flag is HIGH)
try
x = vec(i,j); % Try to copy this cell of array vec in x
j = j+1; % if successful to copy then increment value of j else catch block is executed
catch
flag = 0; % Set flag = 0 (or low) to end the while loop
end
end
j = j - 1; % The value of j comes out to be one greater than number of columns hence decrementing by 1
%
% WE HAVE THE NUMBER OF COLUMNS !!
%
% WE WILL PERFORM SAME THING TO GET THE NUMBER OF ROWS BY INCREMENTING i AND
% KEEPING j AS CONSTANT
flag=1;
while(flag==1)
try
x = vec(i,j);
i = i+1;
catch
flag = 0;
end
end
i = i - 1;
% i is the number of rows in the matrix or array
% j is the number of columns in the matrix
dim = [i,j] % vector named dim(or say matrix named dim) contains the required output
dim contains the size of vec
I'm a 'space-complexity' neophyte and was given a problem.
Suppose I have an array of arbitrary integers:
[1,0,4,2,1,0,5]
How would I reorder this array to have all the zeros at one end:
[1,4,2,1,5,0,0]
...and compute the count of non-zero integers (in this case: 5)?
... in O(n) runtime with O(1) space complexity?
I'm not good at this.
My background is more environmental engineering than computer science so I normally think in the abstract.
I thought I could do a sort, then count the non-zero integers.
Then I thought I could merely do a element-per-element copy as I re-arrange the array.
Then I thought something like a bubble sort, switching neighboring elements till I reached the end with the zeroes.
I thought I could save on the 'space-complexity' via shift array-members' addresses, being that the array point points to the array, with offsets to its members.
I either enhance the runtime at the expense of the space complexity or vice versa.
What's the solution?
Two-pointer approach will solve this task and keep within the time and memory constraints.
Start by placing one pointer at the end, another at the start of the array. Then decrement the end pointer until you see the first non-zero element.
Now the main loop:
If the start pointer points to zero, swap it with the value pointed
by the end pointer; then decrement the end pointer.
Always increment the start pointer.
Finish when start pointer becomes greater than or equal to the end
pointer.
Finally, return the position of the start pointer - that's the number of nonzero elements.
This is the Swift code for the smart answer provided by #kfx
func putZeroesToLeft(inout nums: [Int]) {
guard var firstNonZeroIndex: Int = (nums.enumerate().filter { $0.element != 0 }).first?.index else { return }
for index in firstNonZeroIndex..<nums.count {
if nums[index] == 0 {
swap(&nums[firstNonZeroIndex], &nums[index])
firstNonZeroIndex += 1
}
}
}
Time complexity
There are 2 simple (not nested) loops repeated max n times (where n is the length of input array). So time is O(n).
Space complexity
Beside the input array we only use the firstAvailableSlot int var. So the space is definitely a constant: O(1).
As indicated by the other answers, the idea is to have two pointers, p and q, one pointing at the end of the array (specifically at the first nonzero entry from behind) and the other pointing at the beginning of the array. Scan the array with q, each time you hit a 0, swap elements pointed to by p and q, increment p and decrement q (specifically, make it point to the next nonzero entry from behind); iterate as long as p < q.
In C++, you could do something like this:
void rearrange(std::vector<int>& v) {
int p = 0, q = v.size()-1;
// make q point to the right position
while (q >= 0 && !v[q]) --q;
while (p < q) {
if (!v[p]) { // found a zero element
std::swap(v[p], v[q]);
while (q >= 0 && !v[q]) --q; // make q point to the right position
}
++p;
}
}
Start at the far end of the array and work backwards. First scan until you hit a nonzero (if any). Keep track of the location of this nonzero. Keep scanning. Whenever you encounter a zero -- swap. Otherwise increase the count of nonzeros.
A Python implementation:
def consolidateAndCount(nums):
count = 0
#first locate last nonzero
i = len(nums)-1
while nums[i] == 0:
i -=1
if i < 0:
#no nonzeros encountered
return 0
count = 1 #since a nonzero was encountered
for j in range(i-1,-1,-1):
if nums[j] == 0:
#move to end
nums[j], nums[i] = nums[i],nums[j] #swap is constant space
i -=1
else:
count += 1
return count
For example:
>>> nums = [1,0,4,2,1,0,5]
>>> consolidateAndCount(nums)
5
>>> nums
[1, 5, 4, 2, 1, 0, 0]
The suggested answers with 2 pointers and swapping are changing the order of non-zero array elements which is in conflict with the example provided. (Although he doesn't name that restriction explicitly, so maybe it is irrelevant)
Instead, go through the list from left to right and keep track of the number of 0s encountered so far.
Set counter = 0 (zeros encountered so far).
In each step, do the following:
Check if the current element is 0 or not.
If the current element is 0, increment the counter.
Otherwise, move the current element by counter to the left.
Go to the next element.
When you reach the end of the list, overwrite the values from array[end-counter] to the end of the array with 0s.
The number of non-zero integers is the size of the array minus the counted zeros.
This algorithm has O(n) time complexity as we go at most twice through the whole array (array of all 0s; we could modify the update scheme a little to only go through at most exactly once though). It only uses an additional variable for counting which satisfies the O(1) space constraint.
Start with iterating over the array (say, i) and maintaining count of zeros encountered (say zero_count) till now.
Do not increment the iterative counter when the current element is 0. Instead increment zero_count.
Copy the value in i + zero_count index to the current index i.
Terminate the loop when i + zero_count is greater than array length.
Set the remaining array elements to 0.
Pseudo code:
zero_count = 0;
i = 0;
while i + zero_count < arr.length
if (arr[i] == 0) {
zero_count++;
if (i + zero_count < arr.length)
arr[i] = arr[i+zero_count]
} else {
i++;
}
while i < arr.length
arr[i] = 0;
i++;
Additionally, this also preserves the order of non-zero elements in the array,
You can actually solve a more generic problem called the Dutch national flag problem, which is used to in Quicksort. It partitions an array into 3 parts according to a given mid value. First, place all numbers less than mid, then all numbers equal to mid and then all numbers greater than mid.
Then you can pick the mid value as infinity and treat 0 as infinity.
The pseudocode given by the above link:
procedure three-way-partition(A : array of values, mid : value):
i ← 0
j ← 0
n ← size of A - 1
while j ≤ n:
if A[j] < mid:
swap A[i] and A[j]
i ← i + 1
j ← j + 1
else if A[j] > mid:
swap A[j] and A[n]
n ← n - 1
else:
j ← j + 1
I have a question in the solution I'm referring for the below question
A magic index in an array A[l.. .n-l] is defined to be an index such
that A[i] = i. Given a sorted array of distinct integers, write a
method to find a magic index, if one exists, in array A.
The solution I'm referring looks like. Assume 's' stands for start and 'e' stands for end.
int fun(int a[], int s, int e)
{
if(s > e || s < 0 || e >= array.length)
return -1;
mid = (s + e)/2;
if(mid == a[mid])
return mid;
else if(mid < a[mid])
return fun(a, s, mid-1);
else
return fun(a, mid+1, e);
}
I'm not sure about the ending condition here.
I feel the ending condition should just be
if(s > e)
return -1;
Let's consider the two extreme cases when the magic index is not present
CASE 1 - going left till index 0
Say the array looks as follows a[] = {2,10,20,30,40,50}
mid = (0+6)/2 = 3 , call fun(0,2)
mid = (0+2)/2 = 1 , call fun(0,0)
mid = (0+0)/2 = 0 , call fun(0,-1)
since start > end, -1 is returned
CASE 2 - going right till the last element
Say the array looks as follows a[] = {-20,-10,-5,-4,-3,30,80}
mid = (0+6)/2 = 3 , call fun(4,6)
mid = (4+6)/2 = 5 , call fun(6,6)
mid = (6+6)/2 = 6 , call fun(7,6)
since start > end, -1 is returned
Moreover, I feel the extra conditions given in the solution can never be reached.
I feel s<0 cannot be reached because we are never subtracting anything from 's'. I feel the smallest value that 's' can take is 0. Maybe 'e' can be < 0, but not 's'
Also I feel e >= array.length is not possible since we are never adding anything to 'e'. Maybe 's' can be greater than or equal to array.length but not 'e'
Youre right s>e is enough. S can never be below zero since it's either preserved or equal to (s+e)/2+1>=s+1 (since e>=s), so it's always larger or equal to the initial value passed, which is zero. Similarly it can be shown that e<=n-1 always, so the extra conditions are redundant.
Given the following problem , I'd appreciate for any corrections since I have no solution
for the current question (taken from one of my professor's exams !!!) :
Remark: this is no homework !
Problem:
Given two sorted arrays A (with length n) & B (with length m) , where each
element (in both arrays) is a real number , and a number X (also a real number) ,
we'd like to know whether or not exists a ∈ A and b ∈ B , such as :
a + b = X , in O(n+m) running time .
Solution :
First , we start to check from the end of both arrays , since we don't need the numbers that are bigger than X :
i = n
k = m
while A[i] > X , i = i -1
while B[k] > X , k = k -1
Define j = 0 .
Now start running from the current i in A , and from j in B :
while i > 0 , j < k :
if A[i]+B[j] == X , then return both cells
else j = j+1 , i = i -1
In the end we'd have either the two elements , or we'd reach out of bounds in one
or both of the arrays , which means that no two elements such a + b = X are indeed exist .
Any remarks would be much appreciated
Thanks
You shouldn't adjust i and j at the same time. If the sum is too big, you should decrease i. If it is too small, increase j.
This problem is a special case of the following question:
Find number in sorted matrix (Rows n Columns) in O(log n)
Consider a matrix filled with the C[i,j] = A[i] + B[j], then starting from one of the corners, you decrease i if the sum is too big, and if it's too small, increase j.
Of course you don't have to create and/or fill this matrix C in your program, just assume you know any element of this matrix: it's A[i] + B[j], you can compute it immediately at any moment. The resulting algorithm is O(m+n).
I have the same question for homework.
I worked out before I check it on the internet.
Here is my solution(Python), hope some big guys see it and help me to improve it
# 1.3. Given two sorted arrays a and b and number S. Find two elements such that sum a[i] + b[j] = S.Time O(n).
def find_elem_sum(alist, blist, S): # O(n)
if alist is None or alist == [] or blist is None or blist == []:
return None
# find the numbers which are less than S in the lists
#
#
# pretend it is done
a_length = len(alist)
b_length = len(blist)
a_index, b_index = 0, 0
count = 0
while alist and a_index < a_length and b_index < b_length:
count += 1
if alist[a_index] + blist[b_index] < S:
if a_index < a_length - 1:
a_index += 1
if a_index == a_length - 1:
b_index += 1;
continue
elif alist[a_index] + blist[b_index] > S:
alist = alist[:a_index]
a_length = len(alist)
a_index = a_length - 1
elif alist[a_index] + blist[b_index] == S:
return [a_index, b_index, count]
return None