What's the correct code for this pseudocode - pseudocode

I'm not quite getting pseudocode FOR loop thing.
What would be the correct code (in any language) for this pseudocode?
function myFunction(arr[])
for i = 0 to length(arr)
if (arr[i] > i) then
j = i
while (j < length(arr)) and (arr[j] >= j)
j = j + 1
temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
i = 0

Here it is, in C# (or Java, if you decapitalize "Length"):
void myFunction(int[] arr)
{
for(int i = 0; i < arr.Length; i++)
{
if(arr[i] > i)
{
int j = i;
while(j < arr.Length && arr[j] >= j)
j = j + 1;
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i = 0;
}
}
}
Using while instead of for:
void myFunction(int[] arr)
{
int i = 0;
while(i < arr.Length)
{
if(arr[i] > i)
{
int j = i;
while(j < arr.Length && arr[j] >= j)
j = j + 1;
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i = 0;
}
i++;
}
}
Note the indentation structure of the pseudocode:
function myFunction(arr[])
for i = 0 to length(arr)
if (arr[i] > i) then
...
This means that everything underneath the for declaration is inside the loop, and everything underneath the if, including setting i to 0, will be inside the conditional block. Given this fact, it must be the case that i will start again at 1 if the if statement is entered. What would happen if the code were as below?
void myFunction(int[] arr)
{
int i = 0;
while(i < arr.Length)
{
if(arr[i] > i)
{
int j = i;
while(j < arr.Length && arr[j] >= j)
j = j + 1;
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i++;
i = 0;
}
}
}
In the case arr[i] <= i, the loop never terminates.
You should always assume the last operation of an iterative loop is the shifting of the index, unless explicitly stated otherwise. This is how a for loop must behave, and how a while implementation ought to (by convention).
The code itself looks to be an attempt at a bubble sort implementation, but is sorting based on comparison against the index, rather than the other elements. I am not sure what it is meant to achieve.

Related

Is declaring a new intger inside a loop changes the space complexity?

Is declaring a new intger inside a loop changes the space complexity of the metohd?
for exampe if i'm looking at the follwoing 2 methods, is both of the methods space complexity is O(1)? or in the first method becuase I'm declaring the variable c over and over until the loop end it's space complexity is O(n)?
public static int what (int []a) {
int temp = 0;
for (int i = 0; i < a.length; i++) {
for (int j = i; j < a.length; j++) {
**int c = f(a, i, j);**
if (c % 2 == 0) {
if (j - i + 1 > temp)
temp = j - i + 1;
}
}
}
return temp;
}
public static int what (int []a) {
int temp = 0;
**int c;**
for (int i = 0; i < a.length; i++) {
for (int j = i; j < a.length; j++) {
**c = f(a, i, j);**
if (c % 2 == 0) {
if (j - i + 1 > temp)
temp = j - i + 1;
}
}
}
return temp;
}
Not sure if it's relevant to the question but also attahced the f method.
private static int f (int[]a, int low, int high)
{
int res = 0;
for (int i=low; i<=high; i++)
res += a[i];
return res;
}
When you declare a variable inside the for loop it goes out of scope when the iteration ends and gets re declared in the next iteration so you are not declaring n variables, you are declaring a variable n times

Which is faster, if inside a loop, or a just the loop?

I am trying to understand some concepts of performance in code.
If there is, for instance, a 2d boolean array with 5 trues inside it,
if we want to change all the elements in the array to false, which code would be faster?
number1:
for (i = 0; i < arr.length; i++) {
for (j = 0; j < arr[0].length; j++) {
arr[i][j] = false;
}
}
number2:
for (i = 0; i < arr.length; i++) {
for (j = 0; j < arr[0].length; j++) {
if (arr[i][j])
arr[i][j] = false;
}
}
You can measure it by using console.time() and console.timeEnd():
Number 1:
console.time('loop');
for (i = 0; i < arr.length; i++) {
for (j = 0; j < arr[0].length; j++) {
arr[i][j] = false;
}
}
console.timeEnd('loop');
loop: 0.046142578125ms
Number 2:
console.time('loop');
for (i = 0; i < arr.length; i++) {
for (j = 0; j < arr[0].length; j++) {
if (arr[i][j])
arr[i][j] = false;
}
}
console.timeEnd('loop');
loop: 0.031982421875ms
The array I used was arr[1][135] big and had 5 values in the second array that were true.
As you can see the loop with the if clause is faster.

Dividing n numbers into two groups each having sum less than equals k

There are n numbers, ranging 1-100. n ranges in 1-1000.
Another number k. Its bounds are 1 <= k <= 10^6
How to check if its possible to divide the given n numbers in two sets such that the sum of both group numbers is <=k.
I am looking for a high level implementation approach or an algorithm which will return true if the division is possible.
A DP based solution with a complexity of O(n*sum)
for (int i = 0; i < n; i++) {
sum += a[i];
}
int[][] dp = new int[n + 1][sum + 1];
for (int i = 0; i <= n; i++) {
dp[i][0] = 1;
}
for (int i = 0; i < n; i++) {
for (int j = 0; j <= sum; j++) {
dp[i + 1][j] = dp[i][j];
if (a[i] <= j) {
dp[i + 1][j] |= dp[i][j - a[i]];
}
}
}
for (int i = sum / 2; i >= 0; i--) {
if (dp[n][i] == 1) {
int x = sum - i;
if (x > k || i > k) {
System.out.println("NO");
} else {
System.out.println("YES");
}
break;
}
}

Lomuto Partition in Quick Sort

All of the Lomuto Partion implementations of Quick Sort have two swaps. Can we just use one swap, and delete the swap codes that outside the for loop? When j == high, the code can swap arr[high] with arr[i]. Following is my code:
1. Original LomutoPartion() implementation:
int lomutoPartition(int arr[], int low, int high)
{
int pivot = arr[high];
int i = (low-1);
for (int j = low; j < high; j++)
{
if (arr[j] <= pivot)
{
i++;
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
int temp = arr[high - 1];
arr[high - 1] = arr[i];
arr[i] = temp;
return i;
}
2. My LomutoPartition() implementation:
int lomutoPartition(int arr[], int low, int high)
{
int pivot = arr[high];
int i = (low-1);
for (int j = low; j <= high; j++)
{
if (arr[j] <= pivot)
{
i++;
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
return i;
}

Find Minimum Number in a Sorted and Rotated Array with Duplicate elements

I have worked on this problem for days but still, couldn't figure out a way to solve it. My solution can't solve some edge cases.
Problem:
Given an array and sorted in ascending order, rotate the array by k elements, find the index of the minimum number of the array(first element of the original non-rotated array).For example:
1. Give {3,4,1,3,3}, return 2.
2. Give {3,3,3,3,3}, return 0.
3. Give {1,1,4,1,1,1}, return 3.
Without duplicates, this problem can be solved in O(logn) time using binary search, with duplicates a modified binary search can be used, worst case time complexity is O(n).
My code:
public int FindPivot(int[] array)
{
var i = 0;
var j = array.Length - 1;
while (i < j)
{
var mid = i + (j - i) / 2 + 1;
if (array[mid] < array[array.Length - 1])
{
j = mid - 1;
}
else if (array[mid] > array[array.Length - 1])
{
i = mid;
}
else
{
if (array[mid] == array[j])
{
j--;
}
if (array[mid] == array[i])
{
i++;
}
}
}
return i+1;
}
It doesn't work if the input is {3,3,1,3,3,3,3,3}, it returns 3 while the correct answer is 2. Because at the last step is i points to index 2 and j moves from index 3 to index 2, it gets the correct element but i+1 makes the result wrong.What am I missing here?
I have modified your code as below and it seems works for all cases.
I cannot think of any good way to handle all the corner cases, because your original code kind of mix up the concept of the algorithm without duplicate elements (divide into two sub arrays) and two-pointers algorithm when there is duplicate elements.
I would say the problem is that the else case which is moving the two pointers did not cover all cases, like there are chances that you will go into else block with array[i] < array[mid]
Therefore I just modified it using newbie's method: Add two variables to keep track the minimum element and minimum index we found. Update it whenever the pointers move to cover all the cases possible. Return the index at the end. You cannot do something like return i+1 as it won't handle case for k = 0 which is no rotation at all ( {1,2,3,4})
The modified code is written in C# which I guess from your sample code.
PS: Though in average, this is faster than O(N) if the data is partially sorted without duplicate elements, it's worst case is still O(N) as you mentioned. So if I were you, I would just do a simple iteration and find the first minimum element...
Also from this reference, O(N) is the optimal you can reach if there are duplicate elements.
http://ideone.com/v3KVwu
using System;
public class Test
{
public static int FindPivot(int[] array)
{
var i = 0;
var j = array.Length - 1;
var ans = 1<<20;
var idx = 1<<20;
while (i < j)
{
var mid = i + (j - i) / 2 + 1;
// Console.WriteLine(String.Format("{0}, {1}, {2}", i, mid, j));
if (array[mid] < array[array.Length - 1])
{
if(array[mid] < ans || (array[mid] == ans && mid < idx)) { ans = array[mid]; idx = mid;}
j = mid - 1;
}
else if (array[mid] > array[array.Length - 1])
{
i = mid;
}
else
{
// Here did not consider case if array[i] < mid
if(array[j] < ans || (array[j] == ans && j < idx)) { ans = array[j]; idx = j;}
if(array[i] < ans || (array[i] == ans && i < idx)) { ans = array[i]; idx = i;}
if (array[mid] == array[j])
{
j--;
}
if (array[mid] == array[i])
{
i++;
}
}
}
if(array[j] < ans || (array[j] == ans && j < idx)) { ans = array[j]; idx = j;}
if(array[i] < ans || (array[i] == ans && i < idx)) { ans = array[i]; idx = i;}
Console.WriteLine("Minimum = " + ans);
return idx;
}
public static void Main()
{
int []a = {7,7,7,7,8,8,9,9,1,2,2,2,7,7};
int []b = {3,3,1,3,3,3,3,3};
int []c = {1,2,3,4};
int []d = {4,4,4,4};
int []e = {3,3,3,3,3,3,3,1,3};
int []f = {4,5,6,7,1,1,1,1};
Console.WriteLine(FindPivot(a));
Console.WriteLine(FindPivot(b));
Console.WriteLine(FindPivot(c));
Console.WriteLine(FindPivot(d));
Console.WriteLine(FindPivot(e));
Console.WriteLine(FindPivot(f));
}
}
Based on #shole's answer, I modified the code a little bit to cover cases like {1,1,1,1,3,1,1,1,1,1,1,1,1}.
public int FindPivot(int[] nums)
{
var i = 0;
var j = nums.Length - 1;
var ans = int.MaxValue;
var idx = int.MaxValue;
while (i < j)
{
var mid = i + (j - i) / 2 + 1;
if (nums[mid] < nums[nums.Length - 1])
{
if (nums[mid] < ans || (nums[mid] == ans && mid < idx)) { ans = nums[mid]; idx = mid; }
j = mid - 1;
}
else if (nums[mid] > nums[nums.Length - 1])
{
i = mid;
}
else
{
if (nums[j] < ans || (nums[j] == ans && j < idx)) { ans = nums[j]; idx = j; }
if (nums[mid] == nums[j])
{
j--;
}
if (nums[mid] == nums[i])
{
i++;
}
}
}
// Deal with cases like {1,1,1,1,1}
if (nums[i] == nums[nums.Length - 1] && nums[i] == nums[0] && i == j)
{
return 0;
}
if (nums[j] < ans || (nums[j] == ans && j < idx)) { ans = nums[j]; idx = j; }
return idx;
}

Resources