Computing the height of a tree C# - c#

I have been writing this code for computing the height of a tree in c#. the input for this question would be first: the number of nodes and then the quantity for each of them. then the output would be the height of the tree.
input
5
4 -1 4 1 1
output
3
public long Solve(long nodeCount, long[] tree)
{
List<long>[] Node = new List<long>[nodeCount];
long root = 0;
for(int i =0;i<nodeCount;i++ )
{
Node[i] = new List<long>();
}
for(int j =0; j<nodeCount;j++)
{
if (tree[j] == -1)
root = j;
else
Node[tree[j]].Add(j);
}
Queue<long> Q = new Queue<long>();
Q.Enqueue(root);
long Height = 0;
while(Q.Any())
{
for(int i =0; i<Q.Count(); i++)
{
long nodee = Q.Dequeue();
if(Node[nodee] != null)
{
foreach(long N in Node[nodee])
{
Q.Enqueue(N);
}
}
}
Height = Height+1;
}
return Height;
}
this code is returning wrong results to my test cases. what is the problem?

You can swap the pointer direction of the tree nodes in O(n) when using 2 arrays (as pointer for the 2 children of the indexed node):
int size = 5;
int arr[size] = {4, -1, 4, 1, 1};
int a[size];
int b[size];
for (int i = 0; i < size; i++) {
a[i] = -1;
b[i] = -1;
} // I'm not c++ expert (I guess there are better way of init array with the same value...
int root = -1;
for (int i = 0; i < size; i++) {
if (arr[i] == -1)
root = i;
else if (a[arr[i]] != -1)
b[arr[i]] = i;
else
a[arr[i]] = i;
}
This is done in 1 for loop.
You can now use those 2 array to get you height is recursive way:
int findHeight(int current, int count, int a[], int b[]) {
int maxV = count;
if (a[current] > -1)
maxV = max(findHeight(a[current], count + 1, a, b), maxV);
if (b[current] > -1)
maxV = max(findHeight(b[current], count + 1, a, b), maxV);
return maxV;
}
Execute this with:
int height = findHeight(root, 1, a, b); //(as root is the first level)
Total run time complexity is O(n)
Hope that help

Related

Getting Time limit Exceed for last 3 Test Cases in a Program:C# [duplicate]

Given an array of n integers and a number, d, perform left rotations on the array. Then print the updated array as a single line of space-separated integers.
Sample Input:
5 4
1 2 3 4 5
The first line contains two space-separated integers denoting the respective values of n (the number of integers) and d (the number of left rotations you must perform).
The second line contains n space-separated integers describing the respective elements of the array's initial state.
Sample Output:
5 1 2 3 4
static void Main(String[] args)
{
string[] arr_temp = Console.ReadLine().Split(' ');
int n = Int32.Parse(arr_temp[0]);
int d = Int32.Parse(arr_temp[1]);
string[] arr = Console.ReadLine().Split(' ');
string[] ans = new string[n];
for (int i = 0; i < n; ++i)
{
ans[(i + n - d) % n] = arr[i];
}
for (int j = 0; j < n; ++j)
{
Console.Write(ans[j] + " ");
}
}
How to use less memory to solve this problem?
This will use less memory in most cases as the second array is only as big as the shift.
public static void Main(string[] args)
{
int[] n = { 1, 2, 3, 4, 5 };
LeftShiftArray(n, 4);
Console.WriteLine(String.Join(",", n));
}
public static void LeftShiftArray<T>(T[] arr, int shift)
{
shift = shift % arr.Length;
T[] buffer = new T[shift];
Array.Copy(arr, buffer, shift);
Array.Copy(arr, shift, arr, 0, arr.Length - shift);
Array.Copy(buffer, 0, arr, arr.Length - shift, shift);
}
This problem can get a bit tricky but also has a simple solution if one is familiar with Queues and Stacks.
All I have to do is define a Queue (which will contain the given array) and a Stack.
Next, I just have to Push the Dequeued index to the stack and Enqueue the Popped index in the Queue and finally return the Queue.
Sounds confusing? Check the code below:
static int[] rotLeft(int[] a, int d) {
Queue<int> queue = new Queue<int>(a);
Stack<int> stack = new Stack<int>();
while(d > 0)
{
stack.Push(queue.Dequeue());
queue.Enqueue(stack.Pop());
d--;
}
return queue.ToArray();
}
Do you really need to physically move anything? If not, you could just shift the index instead.
Actually you asked 2 questions:
How to efficiently rotate an array?
and
How to use less memory to solve this problem?
Usually efficiency and low memory usage are mutually exclusive. So I'm going to answer your second question, still providing the most efficient implementation under that memory constraint.
The following method can be used for both left (passing negative count) or right (passing positive count) rotation. It uses O(1) space (single element) and O(n * min(d, n - d)) array element copy operations (O(min(d, n - d)) array block copy operations). In the worst case scenario it performs O(n / 2) block copy operations.
The algorithm is utilizing the fact that
rotate_left(n, d) == rotate_right(n, n - d)
Here it is:
public static class Algorithms
{
public static void Rotate<T>(this T[] array, int count)
{
if (array == null || array.Length < 2) return;
count %= array.Length;
if (count == 0) return;
int left = count < 0 ? -count : array.Length + count;
int right = count > 0 ? count : array.Length - count;
if (left <= right)
{
for (int i = 0; i < left; i++)
{
var temp = array[0];
Array.Copy(array, 1, array, 0, array.Length - 1);
array[array.Length - 1] = temp;
}
}
else
{
for (int i = 0; i < right; i++)
{
var temp = array[array.Length - 1];
Array.Copy(array, 0, array, 1, array.Length - 1);
array[0] = temp;
}
}
}
}
Sample usage like in your example:
var array = Enumerable.Range(1, 5).ToArray(); // { 1, 2, 3, 4, 5 }
array.Rotate(-4); // { 5, 1, 2, 3, 4 }
Isn't using IEnumerables better? Since It won't perform all of those maths, won't allocate that many arrays, etc
public static int[] Rotate(int[] elements, int numberOfRotations)
{
IEnumerable<int> newEnd = elements.Take(numberOfRotations);
IEnumerable<int> newBegin = elements.Skip(numberOfRotations);
return newBegin.Union(newEnd).ToArray();
}
IF you don't actually need to return an array, you can even remove the .ToArray() and return an IEnumerable
Usage:
void Main()
{
int[] n = { 1, 2, 3, 4, 5 };
int d = 4;
int[] rotated = Rotate(n,d);
Console.WriteLine(String.Join(" ", rotated));
}
I have also tried this and below is my approach...
Thank you
public static int[] RotationOfArray(int[] A, int k)
{
if (A == null || A.Length==0)
return null;
int[] result =new int[A.Length];
int arrayLength=A.Length;
int moveBy = k % arrayLength;
for (int i = 0; i < arrayLength; i++)
{
int tmp = i + moveBy;
if (tmp > arrayLength-1)
{
tmp = + (tmp - arrayLength);
}
result[tmp] = A[i];
}
return result;
}
I have tried to used stack and queue in C# to achieve the output as follows:
public int[] rotateArray(int[] A, int rotate)
{
Queue<int> q = new Queue<int>(A);
Stack<int> s;
while (rotate > 0)
{
s = new Stack<int>(q);
int x = s.Pop();
s = new Stack<int>(s);
s.Push(x);
q = new Queue<int>(s);
rotate--;
}
return q.ToArray();
}
I've solve the challange from Hackerrank by following code. Hope it helps.
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace ConsoleApp1
{
class ArrayLeftRotationSolver
{
TextWriter mTextWriter;
public ArrayLeftRotationSolver()
{
mTextWriter = new StreamWriter(#System.Environment.GetEnvironmentVariable("OUTPUT_PATH"), true);
}
public void Solve()
{
string[] nd = Console.ReadLine().Split(' ');
int n = Convert.ToInt32(nd[0]);
int d = Convert.ToInt32(nd[1]);
int[] a = Array.ConvertAll(Console.ReadLine().Split(' '), aTemp => Convert.ToInt32(aTemp))
;
int[] result = rotLeft(a, d);
mTextWriter.WriteLine(string.Join(" ", result));
mTextWriter.Flush();
mTextWriter.Close();
}
private int[] rotLeft(int[] arr, int shift)
{
int n = arr.Length;
shift %= n;
int[] vec = new int[n];
for (int i = 0; i < n; i++)
{
vec[(n + i - shift) % n] = arr[i];
}
return vec;
}
static void Main(string[] args)
{
ArrayLeftRotationSolver solver = new ArrayLeftRotationSolver();
solver.Solve();
}
}
}
Hope this helps.
public static int[] leftrotation(int[] arr, int d)
{
int[] newarr = new int[arr.Length];
var n = arr.Length;
bool isswapped = false;
for (int i = 0; i < n; i++)
{
int index = Math.Abs((i) -d);
if(index == 0)
{
isswapped = true;
}
if (!isswapped)
{
int finalindex = (n) - index;
newarr[finalindex] = arr[i];
}
else
{
newarr[index] = arr[i];
}
}
return newarr;
}
Take the Item at position 0 and add it at the end. remove the item at position 0. repeat n times.
List<int> iList = new List<int>();
private void shift(int n)
{
for (int i = 0; i < n; i++)
{
iList.Add(iList[0]);
iList.RemoveAt(0);
}
}
An old question, but I thought I'd add another possible solution using just one intermediate array (really, 2 if you include the LINQ Take expression). This code rotates to right rather than left, but may be useful nonetheless.
public static Int32[] ArrayRightRotation(Int32[] A, Int32 k)
{
if (A == null)
{
return A;
}
if (!A.Any())
{
return A;
}
if (k % A.Length == 0)
{
return A;
}
if (A.Length == 1)
{
return A;
}
if (A.Distinct().Count() == 1)
{
return A;
}
for (var i = 0; i < k; i++)
{
var intermediateArray = new List<Int32> {A.Last()};
intermediateArray.AddRange(A.Take(A.Length - 1).ToList());
A = intermediateArray.ToArray();
}
return A;
}
O(1) space, O(n) time solution
I think in theory this is as optimal as it gets, since it makes a.Length in-place swaps and 1 temp variable swap per inner loop.
However I suspect O(d) space solutions would be faster in real life due to less code branching (fewer CPU command pipeline resets) and cache locality (mostly sequential access vs in d element steps).
static int[] RotateInplaceLeft(int[] a, int d)
{
var swapCount = 0;
//get canonical/actual d
d = d % a.Length;
if(d < 0) d += a.Length;
if(d == 0) return a;
for (var i = 0; swapCount < a.Length; i++) //we're done after a.Length swaps
{
var dstIdx = i; //we need this becasue of ~this: https://youtu.be/lJ3CD9M3nEQ?t=251
var first = a[i]; //save first element in this group
for (var j = 0; j < a.Length; j++)
{
var srcIdx = (dstIdx + d) % a.Length;
if(srcIdx == i)// circled around
{
a[dstIdx] = first;
swapCount++;
break; //hence we're done with this group
}
a[dstIdx] = a[srcIdx];
dstIdx = srcIdx;
swapCount++;
}
}
return a;
}
If you take a look at constrains you will see that d <= n (number of rotations <= number of elements in array). Because of that this can be solved in 1 line.
static int[] rotLeft(int[] a, int d)
{
return a.Skip(d).Concat(a.Take(d)).ToArray();
}
// using the same same array, and only one temp variable
// shifting everything several times by one
// works, simple, but slow
public static int[] ArrayRotateLeftCyclical(int[] a, int shift)
{
var length = a.Length;
for (int j = 0; j < shift; j++)
{
int t = a[0];
for (int i = 0; i < length; i++)
{
if (i == length - 1)
a[i] = t;
else
a[i] = a[i + 1];
}
}
return a;
}
Let's say if I have a array of integer 'Arr'. To rotate the array 'n' you can do as follows:
static int[] leftRotation(int[] Arr, int n)
{
int tempVariable = 0;
Queue<int> TempQueue = new Queue<int>(a);
for(int i=1;i<=d;i++)
{
tempVariable = TempQueue.Dequeue();
TempQueue.Enqueue(t);
}
return TempQueue.ToArray();`
}
Let me know if any comments. Thanks!
This is my attempt. It is easy, but for some reason it timed out on big chunks of data:
int arrayLength = arr.Length;
int tmpCell = 0;
for (int rotation = 1; rotation <= d; rotation++)
{
for (int i = 0; i < arrayLength; i++)
{
if (arr[i] < arrayElementMinValue || arr[i] > arrayElementMaxValue)
{
throw new ArgumentException($"Array element needs to be between {arrayElementMinValue} and {arrayElementMaxValue}");
}
if (i == 0)
{
tmpCell = arr[0];
arr[0] = arr[1];
}
else if (i == arrayLength - 1)
{
arr[arrayLength - 1] = tmpCell;
}
else
{
arr[i] = arr[i + 1];
}
}
}
what about this?
public static void RotateArrayAndPrint(int[] n, int rotate)
{
for (int i = 1; i <= n.Length; i++)
{
var arrIndex = (i + rotate) > n.Length ? n.Length - (i + rotate) : (i + rotate);
arrIndex = arrIndex < 0 ? arrIndex * -1 : arrIndex;
var output = n[arrIndex-1];
Console.Write(output + " ");
}
}
It's very straight forward answer.
Main thing is how you choose the start index.
public static List<int> rotateLeft(int d, List<int> arr) {
int n = arr.Count;
List<int> t = new List<int>();
int h = d;
for (int j = 0; j < n; j++)
{
if ((j + d) % n == 0)
{
h = 0;
}
t.Add(arr[h]);
h++;
}
return t;
}
using this code, I have successfully submitted to hacker rank problem,
// fast and beautiful method
// reusing the same array
// using small temp array to store replaced values when unavoidable
// a - array, s - shift
public static int[] ArrayRotateLeftWithSmallTempArray(int[] a, int s)
{
var l = a.Length;
var t = new int[s]; // temp array with size s = shift
for (int i = 0; i < l; i++)
{
// save cells which will be replaced by shift
if (i < s)
t[i] = a[i];
if (i + s < l)
a[i] = a[i + s];
else
a[i] = t[i + s - l];
}
return a;
}
https://github.com/sam-klok/ArraysRotation
public static void Rotate(int[] arr, int steps)
{
for (int i = 0; i < steps; i++)
{
int previousValue = arr[arr.Length - 1];
for (int j = 0; j < arr.Length; j++)
{
int currentValue = arr[j];
arr[j] = previousValue;
previousValue = currentValue;
}
}
}
Here is an in-place Rotate implementation of a trick posted by גלעד ברקן in another question. The trick is:
Example, k = 3:
1234567
First reverse in place each of the two sections delineated by n-k:
4321 765
Now reverse the whole array:
5671234
My implementation, based on the Array.Reverse method:
/// <summary>
/// Rotate left for negative k. Rotate right for positive k.
/// </summary>
public static void Rotate<T>(T[] array, int k)
{
ArgumentNullException.ThrowIfNull(array);
k = k % array.Length;
if (k < 0) k += array.Length;
if (k == 0) return;
Debug.Assert(k > 0);
Debug.Assert(k < array.Length);
Array.Reverse(array, 0, array.Length - k);
Array.Reverse(array, array.Length - k, k);
Array.Reverse(array);
}
Live demo.
Output:
Array: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
Rotate(5)
Array: 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 7
Rotate(-2)
Array: 10, 11, 12, 1, 2, 3, 4, 5, 6, 7, 8, 9

Get next highest number in an ObservableCollection column [duplicate]

Tried to googled it but with no luck.
How can I find the second maximum number in an array with the smallest complexity?
code OR idea will be much help.
I can loop through an array and look for the maximum number
after that, I have the maximum number and then loop the array again to find the second the same way.
But for sure it is not efficient.
You could sort the array and choose the item at the second index, but the following O(n) loop will be much faster.
int[] myArray = new int[] { 0, 1, 2, 3, 13, 8, 5 };
int largest = int.MinValue;
int second = int.MinValue;
foreach (int i in myArray)
{
if (i > largest)
{
second = largest;
largest = i;
}
else if (i > second)
second = i;
}
System.Console.WriteLine(second);
OR
Try this (using LINQ):
int secondHighest = (from number in test
orderby number descending
select number).Distinct().Skip(1).First()
How to get the second highest number in an array in Visual C#?
Answer in C# :
static void Main(string[] args)
{
//let us define array and vars
var arr = new int[]{ 100, -3, 95,100,95, 177,-5,-4,177,101 };
int biggest =0, secondBiggest=0;
for (int i = 0; i < arr.Length; ++i)
{
int arrItem = arr[i];
if(arrItem > biggest)
{
secondBiggest = biggest; //always store the prev value of biggest
//to second biggest...
biggest = arrItem;
}
else if (arrItem > secondBiggest && arrItem < biggest) //if in our
//iteration we will find a number that is bigger than secondBiggest and smaller than biggest
secondBiggest = arrItem;
}
Console.WriteLine($"Biggest Number:{biggest}, SecondBiggestNumber:
{secondBiggest}");
Console.ReadLine(); //make program wait
}
Output : Biggest Number:177, SecondBiggestNumber:101
public static int F(int[] array)
{
array = array.OrderByDescending(c => c).Distinct().ToArray();
switch (array.Count())
{
case 0:
return -1;
case 1:
return array[0];
}
return array[1];
}
static void Main(string[] args)
{
int[] myArray = new int[] { 0, 11, 2, 15, 16, 8, 16 ,8,15};
int Smallest = myArray.Min();
int Largest = myArray.Max();
foreach (int i in myArray)
{
if(i>Smallest && i<Largest)
{
Smallest=i;
}
}
System.Console.WriteLine(Smallest);
Console.ReadLine();
}
This will work even if you have reputation of items in an array
int[] arr = {-10, -3, -3, -6};
int h = int.MinValue, m = int.MinValue;
foreach (var t in arr)
{
if (t == h || t == m)
continue;
if (t > h)
{
m = h;
h = t;
}
else if(t > m )
{
m = t;
}
}
Console.WriteLine("High: {0} 2nd High: {1}", h, m);
//or,
m = arr.OrderByDescending(i => i).Distinct().Skip(1).First();
Console.WriteLine("High: {0} 2nd High: {1}", h, m);
/* we can use recursion */
var counter = 0;
findSecondMax = (arr)=> {
let max = Math.max(...arr);
counter++;
return counter == 1 ? findSecondMax(arr.slice(0,arr.indexOf(max)).concat(arr.slice(arr.indexOf(max)+1))) : max;
}
console.log(findSecondMax([1,5,2,3,0]))
static void Main(string[] args){
int[] arr = new int[5];
int i, j,k;
Console.WriteLine("Enter Array");
for (i = 0; i < 5; i++) {
Console.Write("element - {0} : ", i);
arr[i] = Convert.ToInt32(Console.ReadLine());
}
Console.Write("\nElements in array are: ");
j=arr[0];
k=j;
for (i = 1; i < 5; i++) {
if (j < arr[i])
{
if(j>k)
{
k=j;
}
j=arr[i];
}
}
Console.WriteLine("First Greatest element: "+ j);
Console.WriteLine("Second Greatest element: "+ k);
Console.Write("\n");
}
int max = 0;
int secondmax = 0;
int[] arr = { 2, 11, 15, 1, 7, 99, 6, 85, 4 };
for (int r = 0; r < arr.Length; r++)
{
if (max < arr[r])
{
max = arr[r];
}
}
for (int r = 0; r < arr.Length; r++)
{
if (secondmax < arr[r] && arr[r] < max)
{
secondmax = arr[r];
}
}
Console.WriteLine(max);
Console.WriteLine(secondmax);
Console.Read();
Python 36>=
def sec_max(array: list) -> int:
_max_: int = max(array)
second: int = 0
for element in array:
if second < element < _max_:
second = element
else:
continue
return second
Using below code we can find out second highest number, even array contains multiple max numbers
// int[] myArray = { 25, 25, 5, 20, 50, 23, 10 };
public static int GetSecondHighestNumberForUniqueNumbers(int[] numbers)
{
int highestNumber = 0, Seconhight = 0;
List<int> numberList = new List<int>();
for (int i = 0; i < numbers.Length; i++)
{
//For loop should move forward only for unique items
if (numberList.Contains(numbers[i]))
continue;
else
numberList.Add(numbers[i]);
//find higest number
if (highestNumber < numbers[i])
{
Seconhight = highestNumber;
highestNumber = numbers[i];
} //find second highest number
else if (Seconhight < numbers[i])
{
Seconhight = numbers[i];
}
}
It's not like that your structure is a tree...It's just a simple array, right?
The best solution is to sort the array. And depending on descending or ascending, display the second or the 2nd last element respectively.
The other alternative is to use some inbuilt methods, to get the initial max. Pop that element, and then search for the max again. Don't know C#, so can't give the direct code.
You'd want to sort the numbers, then just take the second largest. Here's a snippet without any consideration of efficiency:
var numbers = new int[] { 3, 5, 1, 5, 4 };
var result=numbers.OrderByDescending(x=>x).Distinct().Skip(1).First();
This isn't too bad:
int[] myArray = new int[] { 0, 1, 2, 3, 13, 8, 5 };
var secondMax =
myArray.Skip(2).Aggregate(
myArray.Take(2).OrderByDescending(x => x).AsEnumerable(),
(a, x) => a.Concat(new [] { x }).OrderByDescending(y => y).Take(2))
.Skip(1)
.First();
It's fairly low on complexity as it only every sorts a maximum of three elements
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
int size;
Console.WriteLine("Enter the size of array");
size = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter the element of array");
int[] arr = new int[size];
for (int i = 0; i < size; i++)
{
arr[i] = Convert.ToInt32(Console.ReadLine());
}
int length = arr.Length;
Program program = new Program();
program.SeconadLargestValue(arr, length);
}
private void SeconadLargestValue(int[] arr, int length)
{
int maxValue = 0;
int secondMaxValue = 0;
for (int i = 0; i < length; i++)
{
if (arr[i] > maxValue)
{
secondMaxValue = maxValue;
maxValue = arr[i];
}
else if(arr[i] > secondMaxValue)
{
secondMaxValue = arr[i];
}
}
Console.WriteLine("First Largest number :"+maxValue);
Console.WriteLine("Second Largest number :"+secondMaxValue);
Console.ReadLine();
}
}
}
My solution below.
class Program
{
static void Main(string[] args)
{
Program pg = new Program();
Console.WriteLine("*****************************Program to Find 2nd Highest and 2nd lowest from set of values.**************************");
Console.WriteLine("Please enter the comma seperated numbers : ");
string[] val = Console.ReadLine().Split(',');
int[] inval = Array.ConvertAll(val, int.Parse); // Converts Array from one type to other in single line or Following line
// val.Select(int.Parse)
Array.Sort(inval);
Console.WriteLine("2nd Highest is : {0} \n 2nd Lowest is : {1}", pg.Return2ndHighest(inval), pg.Return2ndLowest(inval));
Console.ReadLine();
}
//Method to get the 2nd lowest and 2nd highest from list of integers ex 1000,20,-10,40,100,200,400
public int Return2ndHighest(int[] values)
{
if (values.Length >= 2)
return values[values.Length - 2];
else
return values[0];
}
public int Return2ndLowest(int[] values)
{
if (values.Length > 2)
return values[1];
else
return values[0];
}
}
I am giving solution that's in JavaScript, it takes o(n/2) complexity to find the highest and second highest number.
here is the working Fiddler Link
var num=[1020215,2000,35,2,54546,456,2,2345,24,545,132,5469,25653,0,2315648978523];
var j=num.length-1;
var firstHighest=0,seoncdHighest=0;
num[0] >num[num.length-1]?(firstHighest=num[0],seoncdHighest=num[num.length-1]):(firstHighest=num[num.length-1], seoncdHighest=num[0]);
j--;
for(var i=1;i<=num.length/2;i++,j--)
{
if(num[i] < num[j] )
{
if(firstHighest < num[j]){
seoncdHighest=firstHighest;
firstHighest= num[j];
}
else if(seoncdHighest < num[j] ) {
seoncdHighest= num[j];
}
}
else {
if(firstHighest < num[i])
{
seoncdHighest=firstHighest;
firstHighest= num[i];
}
else if(seoncdHighest < num[i] ) {
seoncdHighest= num[i];
}
}
}
Sort the array and take the second to last value?
var result = (from elements in inputElements
orderby elements descending
select elements).Distinct().Skip(1).Take(1);
return result.FirstOrDefault();
namespace FindSecondLargestNumber
{
class Program
{
static void Main(string[] args)
{
int max=0;
int smax=0;
int i;
int[] a = new int[20];
Console.WriteLine("enter the size of the array");
int n = int.Parse(Console.ReadLine());
Console.WriteLine("elements");
for (i = 0; i < n; i++)
{
a[i] = int.Parse(Console.ReadLine());
}
for (i = 0; i < n; i++)
{
if ( a[i]>max)
{
smax = max;
max= a[i];
}
else if(a[i]>smax)
{
smax=a[i];
}
}
Console.WriteLine("max:" + max);
Console.WriteLine("second max:"+smax);
Console.ReadLine();
}
}
}

offset and length are out of bound for array or count is greater than

Getting error for some inputs : offset and length are out of bound for array or count is greater than
public int RemoveDuplicates(int[] nums)
{
int curr = 1;
int prev = 0;
for (int i = 1; i < nums.Length; i++)
{
if(nums[i] > nums[curr] && nums[i] != nums[prev])
{
nums[curr] = nums[i];
curr++;
prev++;
}
}
return curr;
}
I would use the following approach:
int[] nums = { 1, 2, 3, 1 };
nums = nums.Distinct().ToArray();

How to fix Code so that Fibonacci Search Algorithm in C# works properly

Code doesn't always find the index.
I'm trying to implement the fibonacci search algorithm in C#. Sometimes the algorithm doesn't find the element in the array. I wrote Unit Tests to check Code coverage and saw that 10 % of my code isn't reached. I also checked other implementations. I think the problem is this part:
if (GetFibonacciNumberOnIndex(index - 1) == 1 && hayStack[offset + 1] == needle)
return offset + 1;
But logically this should run when one last element is left.
public static int FibSearch(int[] hayStack, int needle)
{
if (hayStack == null)
{
throw new ArgumentNullException(nameof(hayStack), "The array containing values to search in mustn't be null");
}
if (hayStack.Length == 0)
{
return -1;
}
int index = 0;
while (GetFibonacciNumberOnIndex(index) < hayStack.Length)
index++;
int offset = -1;
while (GetFibonacciNumberOnIndex(index) > 1)
{
int i = Math.Min(offset + GetFibonacciNumberOnIndex(index - 2), hayStack.Length - 1);
if (needle < hayStack[i])
index -= 2;
else if (needle > hayStack[i])
{
index--;
offset = i;
}
else
return i;
}
if (GetFibonacciNumberOnIndex(index - 1) == needle && hayStack[offset + 1] == needle)
return offset + 1;
return -404;
}
private static int GetFibonacciNumberOnIndex(int index)
{
if (index < 1)
return 0;
else if (index == 1)
return 1;
int first = 0;
int second = 1;
int tmp = 0;
for (int i = 0; i < index; i++)
{
tmp = first;
first = second;
second = tmp + second;
}
return first;
}
}
I have a file with 1000000 numbers. I'm reading the file and converting the content to an integer array. Finally I'm searching for a number, knowing the number is in the array, but the algorithm returns -404. I verified that the number is in the array using Linq Extension Methods on the integer array.
I create a small sample with binary search. No advantage using Fabonacci search. You can use a streamreader to add the integers one at a time, they will get added and sorted at teh same time.
public class NumIndex:IComparable<NumIndex>
{
public int Number { get; set; }
public int Index { get; set; }
public int CompareTo(NumIndex other)
{
return this.Number.CompareTo(other.Number);
}
}
public static void Main(string[] args)
{
int[] nums = { 8, 4, 8, 1, 6, 3, 4, 32, 43, 5, 8, 95 };
List<NumIndex> intArray = new List<NumIndex>();
int i = 0;
foreach (int num in nums)
{
NumIndex newNum = new NumIndex() { Number = num, Index = i++ };
int index = intArray.BinarySearch(newNum);
if (index > -1)
{
//Item already found, you decide what to do with it, I added all numbers
}
else index = ~index;
intArray.Insert(index, newNum);
}
NumIndex dummy = new NumIndex() { Number = 18, Index = 0 };
int findItemIndex = intArray.BinarySearch(dummy);
if (findItemIndex < -1) throw new Exception("Item not found");
int itemIndex = intArray[].Index;
}

Does adding extra loop at the end of n(log n) algorithm affect the complexity?

I wrote an algorithm to find length of longest increasing sequence in an array.
The algorithm has an array m which will contain the sequence but in some conditions, it doesn't contain the exact sequence. So in such case, I record the index and value which needs to be changed.
This algorithm is n(log n)
Now, to find the actual sequence, I loop through the array m and replace the value recorded in another array. Will my algorithm now still have the complexity if n(log n) ?
Below is the code in C#:
int[] b = { 1, 8, 5, 3, 7, 2, 9 };
int k = 1;
int i = 1;
int N = b.Length;
List<int> m = new List<int>();
int[] lup = new int[b.Length];
m.Add(0);
m.Add(b[0]);
lup[0] = 0;
while (i < N)
{
if (b[i] >= m[k])
{
k = k + 1;
m.Add(b[i]);
}
else
{
if (b[i] < m[1])
{
m[1] = b[i];
}
else
{
int j;
j = Binary_Search(m, b[i], m.Count - 1);
//if the item to be replaced was not the last element, record it
if (m[j] > b[i] && j != k)
{
lup[j] = m[j];
}
m[j] = b[i];
}
}
i = i + 1;
}
Console.WriteLine("The Input Sequence is : " + string.Join("\t", b));
Console.WriteLine("Length of Longest Up Sequence is : " + k.ToString());
List<int> result = new List<int>();
// create result based on m and lup
//DOES THIS LOOP EFFECT PERFORMANCE??
for(int x = 1; x < m.Count; x++)
{
if (lup[x] == 0)
{
result.Add(m[x]);
}
else
{
result.Add(lup[x]);
}
}
Your intuition is correct. Adding this loop is n*(log(n)+1) so it's still n*log(n).

Categories