Increasing Array with Rows - c#

Say I have an an array of numbers:
int[] that = new [] {1, 2, 3, 2, 4, 8, 9, 7};
I'm trying to display them so that the numbers that are increasing have their own line.
For example the result would be:
1 2 3
2 4 8 9
7
I'm able to do the first row using,
for (int i = 1; i < that.Length; i++)
{
if (that[i-1] < that[i])
{
Console.Write(that[i-1] + " ");
}
}
The thing is this works for the first row because 1-3 are increasing but stops after that.
I'm not exactly sure how to continue so that 2 4 8 9, then 7 are written.

I have a feeling this is homework so I'm going to leave the actual coding to you. But here's how to do it in plain language:
Have a variable where we store the previous value. Let's call it oldValue, and start it with zero (if you're only using positive numbers in your array).
Go through the array one item at a time.
Check to see if that number is larger than oldValue.
If FALSE, print the new line character. "\n" in C#.
Print that number and make oldValue equal that number.
Unless your numbers are finished get the next number and go to step 3.

You never create a new line.
int[] arr = new[] {1, 2, 3, 2, 4, 8, 9, 7};
for(var i = 0; i < arr.Length; i++){
if(i == 0 || ((i < arr.Length - 1) && arr[i] < arr[i + 1])){
Console.Write(arr[i]);
} else {
Console.Write("{0}\n", arr[i]);
}
}
Output:
123
2489
7
Couple of remarks:
Avoid the usage of this as a variable name. It's a reserved
keyword.
Use \n as a newline character.

There are a number of ways you can do this, either by appending a string with characters until a lesser one is reached and then using the Console.WriteLine() command to write the entire string at once, or (the easier way given your code) which is to simply test for the new value being lesser than the previous and inserting a newline character into your text.
// Start at zero
for (int i = 0; i < this.Length; i++)
{
// If this is not the first element in the array
// and the new element is smaller than the previous
if (i > 0 && this[i] < this[i-1])
{
// Then insert a new line into the output
Console.Write(Environment.NewLine);
}
Console.Write(this[i] + " ");
}

int[] numbers = new int[] { 1, 2, 3, 2, 4, 8, 9, 7 };
String orderedNumbers = String.Empty;
for (int i = 0; i < numbers.Length; i++)
{
if (i == 0 || numbers[i] > numbers[i - 1])
{
orderedNumbers += numbers[i].ToString();
}
else
{
orderedNumbers += System.Environment.NewLine + numbers[i].ToString();
}
}
MessageBox.Show(orderedNumbers);

Related

Else statement is not recognized in C# what am I missing?

In C# the program is supposed to count how many valid and invalid values were entered by comparing them to the array and then give a total of the correct and incorrect inputs, but when I enter numbers that are outside of the bounds of the if statement the code from the if statement still runs. I've gone back and reviewed videos and the textbook and I cannot see where my if else statement is lacking.
int[] values = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, };
int count = 0;
Console.WriteLine("Enter a value between 0 and 10");
foreach (int v in values)
{
Console.ReadLine();
if (values[v] >= 0 || values[v] <= 10)
{
Console.WriteLine("Enter a value");
count++;
}
else
{
Console.WriteLine("Invalid Entry");
count++;
}
}
Console.WriteLine("You entered {0} correct values", count);
Console.WriteLine("You entered {0} incorrect values", count);
Console.ReadKey();
}
}
(values[v] >= 0 || values[v] <= 10) will always return true, all numbers are either less than 10 or greater than zero. Presumably you want an and (&&) operator to grab values between 0 and 10 inclusive
Also, foreach iterates through the values of an array, not the index, so you don't need to reference values[v], you can just reference v directly (although in your case values[v]==v). Calling values[v] in a foreach runs a huge risk of indexOutOfBounds exceptions. If you want to iterate through the index a straight for loop is more appropriate:
for(int i = 0; i< values.Length; i++)
var myVal = values[i];
Final Edit, you aren't actually checking the user's input
var input = Console.ReadLine();
//you never bothered capturing the user's input with a variable
decimal myNum;
if (decimal.TryParse(input, out myNum)) //did the user give a number?
{
//use myNum instead of values[v]
}
else
{
//process bad input
}
There's a bunch of stuff you can do to make things cleaner, (like removing your array altogether and using for(int i = 0; i< 10; i++) instead, for example), but good code doesn't happen on day 1 (my first few projects make me wanna throw up now), you got this friend.
You have a foreach loop, you do not need to use
if (values[v] >= 0 || values[v] <= 10)
instead, use
if(v >= 0 || v <= 10)
plus your if statement will always return true because the value you have in your array of int is greater than or equals to 0 or less than or equals to 10.
Try to change the array from
int[] values = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, };
to
int[] values = { -5, 1, 2, 3, 11, 5, 6, 13, 8, 9, 15, };
and you should have 4 incorrect count, provided you separate the correct count and incorrect count instead of adding them together using the count.
Separate them into validCount and invalidCount

Mathematically updating the Max of a C# Integer Queue after an Enqueue and Dequeue [duplicate]

Given an array of size n and k, how do you find the maximum for every contiguous subarray of size k?
For example
arr = 1 5 2 6 3 1 24 7
k = 3
ans = 5 6 6 6 24 24
I was thinking of having an array of size k and each step evict the last element out and add the new element and find maximum among that. It leads to a running time of O(nk). Is there a better way to do this?
You have heard about doing it in O(n) using dequeue.
Well that is a well known algorithm for this question to do in O(n).
The method i am telling is quite simple and has time complexity O(n).
Your Sample Input:
n=10 , W = 3
10 3
1 -2 5 6 0 9 8 -1 2 0
Answer = 5 6 6 9 9 9 8 2
Concept: Dynamic Programming
Algorithm:
N is number of elements in an array and W is window size. So, Window number = N-W+1
Now divide array into blocks of W starting from index 1.
Here divide into blocks of size 'W'=3.
For your sample input:
We have divided into blocks because we will calculate maximum in 2 ways A.) by traversing from left to right B.) by traversing from right to left.
but how ??
Firstly, Traversing from Left to Right. For each element ai in block we will find maximum till that element ai starting from START of Block to END of that block.
So here,
Secondly, Traversing from Right to Left. For each element 'ai' in block we will find maximum till that element 'ai' starting from END of Block to START of that block.
So Here,
Now we have to find maximum for each subarray or window of size 'W'.
So, starting from index = 1 to index = N-W+1 .
max_val[index] = max(RL[index], LR[index+w-1]);
for index=1: max_val[1] = max(RL[1],LR[3]) = max(5,5)= 5
Simliarly, for all index i, (i<=(n-k+1)), value at RL[i] and LR[i+w-1]
are compared and maximum among those two is answer for that subarray.
So Final Answer : 5 6 6 9 9 9 8 2
Time Complexity: O(n)
Implementation code:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define LIM 100001
using namespace std;
int arr[LIM]; // Input Array
int LR[LIM]; // maximum from Left to Right
int RL[LIM]; // maximum from Right to left
int max_val[LIM]; // number of subarrays(windows) will be n-k+1
int main(){
int n, w, i, k; // 'n' is number of elements in array
// 'w' is Window's Size
cin >> n >> w;
k = n - w + 1; // 'K' is number of Windows
for(i = 1; i <= n; i++)
cin >> arr[i];
for(i = 1; i <= n; i++){ // for maximum Left to Right
if(i % w == 1) // that means START of a block
LR[i] = arr[i];
else
LR[i] = max(LR[i - 1], arr[i]);
}
for(i = n; i >= 1; i--){ // for maximum Right to Left
if(i == n) // Maybe the last block is not of size 'W'.
RL[i] = arr[i];
else if(i % w == 0) // that means END of a block
RL[i] = arr[i];
else
RL[i] = max(RL[i+1], arr[i]);
}
for(i = 1; i <= k; i++) // maximum
max_val[i] = max(RL[i], LR[i + w - 1]);
for(i = 1; i <= k ; i++)
cout << max_val[i] << " ";
cout << endl;
return 0;
}
Running Code Link
I'll try to proof: (by #johnchen902)
If k % w != 1 (k is not the begin of a block)
Let k* = The begin of block containing k
ans[k] = max( arr[k], arr[k + 1], arr[k + 2], ..., arr[k + w - 1])
= max( max( arr[k], arr[k + 1], arr[k + 2], ..., arr[k*]),
max( arr[k*], arr[k* + 1], arr[k* + 2], ..., arr[k + w - 1]) )
= max( RL[k], LR[k+w-1] )
Otherwise (k is the begin of a block)
ans[k] = max( arr[k], arr[k + 1], arr[k + 2], ..., arr[k + w - 1])
= RL[k] = LR[k+w-1]
= max( RL[k], LR[k+w-1] )
Dynamic programming approach is very neatly explained by Shashank Jain. I would like to explain how to do the same using dequeue.
The key is to maintain the max element at the top of the queue(for a window ) and discarding the useless elements and we also need to discard the elements that are out of index of current window.
useless elements = If Current element is greater than the last element of queue than the last element of queue is useless .
Note : We are storing the index in queue not the element itself. It will be more clear from the code itself.
1. If Current element is greater than the last element of queue than the last element of queue is useless . We need to delete that last element.
(and keep deleting until the last element of queue is smaller than current element).
2. If if current_index - k >= q.front() that means we are going out of window so we need to delete the element from front of queue.
vector<int> max_sub_deque(vector<int> &A,int k)
{
deque<int> q;
for(int i=0;i<k;i++)
{
while(!q.empty() && A[i] >= A[q.back()])
q.pop_back();
q.push_back(i);
}
vector<int> res;
for(int i=k;i<A.size();i++)
{
res.push_back(A[q.front()]);
while(!q.empty() && A[i] >= A[q.back()] )
q.pop_back();
while(!q.empty() && q.front() <= i-k)
q.pop_front();
q.push_back(i);
}
res.push_back(A[q.front()]);
return res;
}
Since each element is enqueued and dequeued atmost 1 time to time complexity is O(n+n) = O(2n) = O(n).
And the size of queue can not exceed the limit k . so space complexity = O(k).
An O(n) time solution is possible by combining the two classic interview questions:
Make a stack data-structure (called MaxStack) which supports push, pop and max in O(1) time.
This can be done using two stacks, the second one contains the minimum seen so far.
Model a queue with a stack.
This can done using two stacks. Enqueues go into one stack, and dequeues come from the other.
For this problem, we basically need a queue, which supports enqueue, dequeue and max in O(1) (amortized) time.
We combine the above two, by modelling a queue with two MaxStacks.
To solve the question, we queue k elements, query the max, dequeue, enqueue k+1 th element, query the max etc. This will give you the max for every k sized sub-array.
I believe there are other solutions too.
1)
I believe the queue idea can be simplified. We maintain a queue and a max for every k. We enqueue a new element, and dequeu all elements which are not greater than the new element.
2) Maintain two new arrays which maintain the running max for each block of k, one array for one direction (left to right/right to left).
3) Use a hammer: Preprocess in O(n) time for range maximum queries.
The 1) solution above might be the most optimal.
You need a fast data structure that can add, remove and query for the max element in less than O(n) time (you can just use an array if O(n) or O(nlogn) is acceptable). You can use a heap, a balanced binary search tree, a skip list, or any other sorted data structure that performs these operations in O(log(n)).
The good news is that most popular languages have a sorted data structure implemented that supports these operations for you. C++ has std::set and std::multiset (you probably need the latter) and Java has PriorityQueue and TreeSet.
Here is the java implementation
public static Integer[] maxsInEveryWindows(int[] arr, int k) {
Deque<Integer> deque = new ArrayDeque<Integer>();
/* Process first k (or first window) elements of array */
for (int i = 0; i < k; i++) {
// For very element, the previous smaller elements are useless so
// remove them from deque
while (!deque.isEmpty() && arr[i] >= arr[deque.peekLast()]) {
deque.removeLast(); // Remove from rear
}
// Add new element at rear of queue
deque.addLast(i);
}
List<Integer> result = new ArrayList<Integer>();
// Process rest of the elements, i.e., from arr[k] to arr[n-1]
for (int i = k; i < arr.length; i++) {
// The element at the front of the queue is the largest element of
// previous window, so add to result.
result.add(arr[deque.getFirst()]);
// Remove all elements smaller than the currently
// being added element (remove useless elements)
while (!deque.isEmpty() && arr[i] >= arr[deque.peekLast()]) {
deque.removeLast();
}
// Remove the elements which are out of this window
while (!deque.isEmpty() && deque.getFirst() <= i - k) {
deque.removeFirst();
}
// Add current element at the rear of deque
deque.addLast(i);
}
// Print the maximum element of last window
result.add(arr[deque.getFirst()]);
return result.toArray(new Integer[0]);
}
Here is the corresponding test case
#Test
public void maxsInWindowsOfSizeKTest() {
Integer[] result = ArrayUtils.maxsInEveryWindows(new int[]{1, 2, 3, 1, 4, 5, 2, 3, 6}, 3);
assertThat(result, equalTo(new Integer[]{3, 3, 4, 5, 5, 5, 6}));
result = ArrayUtils.maxsInEveryWindows(new int[]{8, 5, 10, 7, 9, 4, 15, 12, 90, 13}, 4);
assertThat(result, equalTo(new Integer[]{10, 10, 10, 15, 15, 90, 90}));
}
Using a heap (or tree), you should be able to do it in O(n * log(k)). I'm not sure if this would be indeed better.
here is the Python implementation in O(1)...Thanks to #Shahshank Jain in advance..
from sys import stdin,stdout
from operator import *
n,w=map(int , stdin.readline().strip().split())
Arr=list(map(int , stdin.readline().strip().split()))
k=n-w+1 # window size = k
leftA=[0]*n
rightA=[0]*n
result=[0]*k
for i in range(n):
if i%w==0:
leftA[i]=Arr[i]
else:
leftA[i]=max(Arr[i],leftA[i-1])
for i in range(n-1,-1,-1):
if i%w==(w-1) or i==n-1:
rightA[i]=Arr[i]
else:
rightA[i]=max(Arr[i],rightA[i+1])
for i in range(k):
result[i]=max(rightA[i],leftA[i+w-1])
print(*result,sep=' ')
Method 1: O(n) time, O(k) space
We use a deque (it is like a list but with constant-time insertion and deletion from both ends) to store the index of useful elements.
The index of the current max is kept at the leftmost element of deque. The rightmost element of deque is the smallest.
In the following, for easier explanation we say an element from the array is in the deque, while in fact the index of that element is in the deque.
Let's say {5, 3, 2} are already in the deque (again, if fact their indexes are).
If the next element we read from the array is bigger than 5 (remember, the leftmost element of deque holds the max), say 7: We delete the deque and create a new one with only 7 in it (we do this because the current elements are useless, we have found a new max).
If the next element is less than 2 (which is the smallest element of deque), say 1: We add it to the right ({5, 3, 2, 1})
If the next element is bigger than 2 but less than 5, say 4: We remove elements from right that are smaller than the element and then add the element from right ({5, 4}).
Also we keep elements of the current window only (we can do this in constant time because we are storing the indexes instead of elements).
from collections import deque
def max_subarray(array, k):
deq = deque()
for index, item in enumerate(array):
if len(deq) == 0:
deq.append(index)
elif index - deq[0] >= k: # the max element is out of the window
deq.popleft()
elif item > array[deq[0]]: # found a new max
deq = deque()
deq.append(index)
elif item < array[deq[-1]]: # the array item is smaller than all the deque elements
deq.append(index)
elif item > array[deq[-1]] and item < array[deq[0]]:
while item > array[deq[-1]]:
deq.pop()
deq.append(index)
if index >= k - 1: # start printing when the first window is filled
print(array[deq[0]])
Proof of O(n) time: The only part we need to check is the while loop. In the whole runtime of the code, the while loop can perform at most O(n) operations in total. The reason is that the while loop pops elements from the deque, and since in other parts of the code, we do at most O(n) insertions into the deque, the while loop cannot exceed O(n) operations in total. So the total runtime is O(n) + O(n) = O(n)
Method 2: O(n) time, O(n) space
This is the explanation of the method suggested by S Jain (as mentioned in the comments of his post, this method doesn't work with data streams, which most sliding window questions are designed for).
The reason that method works is explained using the following example:
array = [5, 6, 2, 3, 1, 4, 2, 3]
k = 4
[5, 6, 2, 3 1, 4, 2, 3 ]
LR: 5 6 6 6 1 4 4 4
RL: 6 6 3 3 4 4 3 3
6 6 4 4 4
To get the max for the window [2, 3, 1, 4],
we can get the max of [2, 3] and max of [1, 4], and return the bigger of the two.
Max of [2, 3] is calculated in the RL pass and max of [1, 4] is calculated in LR pass.
Using Fibonacci heap, you can do it in O(n + (n-k) log k), which is equal to O(n log k) for small k, for k close to n this becomes O(n).
The algorithm: in fact, you need:
n inserts to the heap
n-k deletions
n-k findmax's
How much these operations cost in Fibonacci heaps? Insert and findmax is O(1) amortized, deletion is O(log n) amortized. So, we have
O(n + (n-k) log k + (n-k)) = O(n + (n-k) log k)
Sorry, this should have been a comment but I am not allowed to comment for now.
#leo and #Clay Goddard
You can save yourselves from re-computing the maximum by storing both maximum and 2nd maximum of the window in the beginning
(2nd maximum will be the maximum only if there are two maximums in the initial window). If the maximum slides out of the window you still have the next best candidate to compare with the new entry. So you get O(n) , otherwise if you allowed the whole re-computation again the worst case order would be O(nk), k is the window size.
class MaxFinder
{
// finds the max and its index
static int[] findMaxByIteration(int arr[], int start, int end)
{
int max, max_ndx;
max = arr[start];
max_ndx = start;
for (int i=start; i<end; i++)
{
if (arr[i] > max)
{
max = arr[i];
max_ndx = i;
}
}
int result[] = {max, max_ndx};
return result;
}
// optimized to skip iteration, when previous windows max element
// is present in current window
static void optimizedPrintKMax(int arr[], int n, int k)
{
int i, j, max, max_ndx;
// for first window - find by iteration.
int result[] = findMaxByIteration(arr, 0, k);
System.out.printf("%d ", result[0]);
max = result[0];
max_ndx = result[1];
for (j=1; j <= (n-k); j++)
{
// if previous max has fallen out of current window, iterate and find
if (max_ndx < j)
{
result = findMaxByIteration(arr, j, j+k);
max = result[0];
max_ndx = result[1];
}
// optimized path, just compare max with new_elem that has come into the window
else
{
int new_elem_ndx = j + (k-1);
if (arr[new_elem_ndx] > max)
{
max = arr[new_elem_ndx];
max_ndx = new_elem_ndx;
}
}
System.out.printf("%d ", max);
}
}
public static void main(String[] args)
{
int arr[] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
//int arr[] = {1,5,2,6,3,1,24,7};
int n = arr.length;
int k = 3;
optimizedPrintKMax(arr, n, k);
}
}
package com;
public class SlidingWindow {
public static void main(String[] args) {
int[] array = { 1, 5, 2, 6, 3, 1, 24, 7 };
int slide = 3;//say
List<Integer> result = new ArrayList<Integer>();
for (int i = 0; i < array.length - (slide-1); i++) {
result.add(getMax(array, i, slide));
}
System.out.println("MaxList->>>>" + result.toString());
}
private static Integer getMax(int[] array, int i, int slide) {
List<Integer> intermediate = new ArrayList<Integer>();
System.out.println("Initial::" + intermediate.size());
while (intermediate.size() < slide) {
intermediate.add(array[i]);
i++;
}
Collections.sort(intermediate);
return intermediate.get(slide - 1);
}
}
Here is the solution in O(n) time complexity with auxiliary deque
public class TestSlidingWindow {
public static void main(String[] args) {
int[] arr = { 1, 5, 7, 2, 1, 3, 4 };
int k = 3;
printMaxInSlidingWindow(arr, k);
}
public static void printMaxInSlidingWindow(int[] arr, int k) {
Deque<Integer> queue = new ArrayDeque<Integer>();
Deque<Integer> auxQueue = new ArrayDeque<Integer>();
int[] resultArr = new int[(arr.length - k) + 1];
int maxElement = 0;
int j = 0;
for (int i = 0; i < arr.length; i++) {
queue.add(arr[i]);
if (arr[i] > maxElement) {
maxElement = arr[i];
}
/** we need to maintain the auxiliary deque to maintain max element in case max element is removed.
We add the element to deque straight away if subsequent element is less than the last element
(as there is a probability if last element is removed this element can be max element) otherwise
remove all lesser element then insert current element **/
if (auxQueue.size() > 0) {
if (arr[i] < auxQueue.peek()) {
auxQueue.push(arr[i]);
} else {
while (auxQueue.size() > 0 && (arr[i] > auxQueue.peek())) {
auxQueue.pollLast();
}
auxQueue.push(arr[i]);
}
}else {
auxQueue.push(arr[i]);
}
if (queue.size() > 3) {
int removedEl = queue.removeFirst();
if (maxElement == removedEl) {
maxElement = auxQueue.pollFirst();
}
}
if (queue.size() == 3) {
resultArr[j++] = maxElement;
}
}
for (int i = 0; i < resultArr.length; i++) {
System.out.println(resultArr[i]);
}
}
}
static void countDistinct(int arr[], int n, int k)
{
System.out.print("\nMaximum integer in the window : ");
// Traverse through every window
for (int i = 0; i <= n - k; i++) {
System.out.print(findMaximuminAllWindow(Arrays.copyOfRange(arr, i, arr.length), k)+ " ");
}
}
private static int findMaximuminAllWindow(int[] win, int k) {
// TODO Auto-generated method stub
int max= Integer.MIN_VALUE;
for(int i=0; i<k;i++) {
if(win[i]>max)
max=win[i];
}
return max;
}
arr = 1 5 2 6 3 1 24 7
We have to find the maximum of subarray, Right?
So, What is meant by subarray?
SubArray = Partial set and it should be in order and contiguous.
From the above array
{1,5,2} {6,3,1} {1,24,7} all are the subarray examples
n = 8 // Array length
k = 3 // window size
For finding the maximum, we have to iterate through the array, and find the maximum.
From the window size k,
{1,5,2} = 5 is the maximum
{5,2,6} = 6 is the maximum
{2,6,3} = 6 is the maximum
and so on..
ans = 5 6 6 6 24 24
It can be evaluated as the n-k+1
Hence, 8-3+1 = 6
And the length of an answer is 6 as we seen.
How can we solve this now?
When the data is moving from the pipe, the first thought for the data structure came in mind is the Queue
But, rather we are not discussing much here, we directly jump on the deque
Thinking Would be:
Window is fixed and data is in and out
Data is fixed and window is sliding
EX: Time series database
While (Queue is not empty and arr[Queue.back() < arr[i]] {
Queue.pop_back();
Queue.push_back();
For the rest:
Print the front of queue
// purged expired element
While (queue not empty and queue.front() <= I-k) {
Queue.pop_front();
While (Queue is not empty and arr[Queue.back() < arr[i]] {
Queue.pop_back();
Queue.push_back();
}
}
arr = [1, 2, 3, 1, 4, 5, 2, 3, 6]
k = 3
for i in range(len(arr)-k):
k=k+1
print (max(arr[i:k]),end=' ') #3 3 4 5 5 5 6
Two approaches.
Segment Tree O(nlog(n-k))
Build a maximum segment-tree.
Query between [i, i+k)
Something like..
public static void printMaximums(int[] a, int k) {
int n = a.length;
SegmentTree tree = new SegmentTree(a);
for (int i=0; i<=n-k; i++) System.out.print(tree.query(i, i+k));
}
Deque O(n)
If the next element is greater than the rear element, remove the rear element.
If the element in the front of the deque is out of the window, remove the front element.
public static void printMaximums(int[] a, int k) {
int n = a.length;
Deque<int[]> deck = new ArrayDeque<>();
List<Integer> result = new ArrayList<>();
for (int i=0; i<n; i++) {
while (!deck.isEmpty() && a[i] >= deck.peekLast()[0]) deck.pollLast();
deck.offer(new int[] {a[i], i});
while (!deck.isEmpty() && deck.peekFirst()[1] <= i - k) deck.pollFirst();
if (i >= k - 1) result.add(deck.peekFirst()[0]);
}
System.out.println(result);
}
Here is an optimized version of the naive (conditional) nested loop approach I came up with which is much faster and doesn't require any auxiliary storage or data structure.
As the program moves from window to window, the start index and end index moves forward by 1. In other words, two consecutive windows have adjacent start and end indices.
For the first window of size W , the inner loop finds the maximum of elements with index (0 to W-1). (Hence i == 0 in the if in 4th line of the code).
Now instead of computing for the second window which only has one new element, since we have already computed the maximum for elements of indices 0 to W-1, we only need to compare this maximum to the only new element in the new window with the index W.
But if the element at 0 was the maximum which is the only element not part of the new window, we need to compute the maximum using the inner loop from 1 to W again using the inner loop (hence the second condition maxm == arr[i-1] in the if in line 4), otherwise just compare the maximum of the previous window and the only new element in the new window.
void print_max_for_each_subarray(int arr[], int n, int k)
{
int maxm;
for(int i = 0; i < n - k + 1 ; i++)
{
if(i == 0 || maxm == arr[i-1]) {
maxm = arr[i];
for(int j = i+1; j < i+k; j++)
if(maxm < arr[j]) maxm = arr[j];
}
else {
maxm = maxm < arr[i+k-1] ? arr[i+k-1] : maxm;
}
cout << maxm << ' ';
}
cout << '\n';
}
You can use Deque data structure to implement this. Deque has an unique facility that you can insert and remove elements from both the ends of the queue unlike the traditional queue where you can only insert from one end and remove from other.
Following is the code for the above problem.
public int[] maxSlidingWindow(int[] nums, int k) {
int n = nums.length;
int[] maxInWindow = new int[n - k + 1];
Deque<Integer> dq = new LinkedList<Integer>();
int i = 0;
for(; i<k; i++){
while(!dq.isEmpty() && nums[dq.peekLast()] <= nums[i]){
dq.removeLast();
}
dq.addLast(i);
}
for(; i <n; i++){
maxInWindow[i - k] = nums[dq.peekFirst()];
while(!dq.isEmpty() && dq.peekFirst() <= i - k){
dq.removeFirst();
}
while(!dq.isEmpty() && nums[dq.peekLast()] <= nums[i]){
dq.removeLast();
}
dq.addLast(i);
}
maxInWindow[i - k] = nums[dq.peekFirst()];
return maxInWindow;
}
the resultant array will have n - k + 1 elements where n is length of the given array, k is the given window size.
We can solve it using the Python , applying the slicing.
def sliding_window(a,k,n):
max_val =[]
val =[]
val1=[]
for i in range(n-k-1):
if i==0:
val = a[0:k+1]
print("The value in val variable",val)
val1 = max(val)
max_val.append(val1)
else:
val = a[i:i*k+1]
val1 =max(val)
max_val.append(val1)
return max_val
Driver Code
a = [15,2,3,4,5,6,2,4,9,1,5]
n = len(a)
k = 3
sl=s liding_window(a,k,n)
print(sl)
Create a TreeMap of size k. Put first k elements as keys in it and assign any value like 1(doesn't matter). TreeMap has the property to sort the elements based on key so now, first element in map will be min and last element will be max element. Then remove 1 element from the map whose index in the arr is i-k. Here, I have considered that Input elements are taken in array arr and from that array we are filling the map of size k. Since, we can't do anything with sorting happening inside TreeMap, therefore this approach will also take O(n) time.
100% working Tested (Swift)
func maxOfSubArray(arr:[Int],n:Int,k:Int)->[Int]{
var lenght = arr.count
var resultArray = [Int]()
for i in 0..<arr.count{
if lenght+1 > k{
let tempArray = Array(arr[i..<k+i])
resultArray.append(tempArray.max()!)
}
lenght = lenght - 1
}
print(resultArray)
return resultArray
}
This way we can use:
maxOfSubArray(arr: [1,2,3,1,4,5,2,3,6], n: 9, k: 3)
Result:
[3, 3, 4, 5, 5, 5, 6]
Just notice that you only have to find in the new window if:
* The new element in the window is smaller than the previous one (if it's bigger, it's for sure this one).
OR
* The element that just popped out of the window was the current bigger.
In this case, re-scan the window.
for how big k? for reasonable-sized k. you can create k k-sized buffers and just iterate over the array keeping track of max element pointers in the buffers - needs no data structures and is O(n) k^2 pre-allocation.
A complete working solution in Amortised Constant O(1) Complexity.
https://github.com/varoonverma/code-challenge.git
Compare the first k elements and find the max, this is your first number
then compare the next element to the previous max. If the next element is bigger, that is your max of the next subarray, if its equal or smaller, the max for that sub array is the same
then move on to the next number
max(1 5 2) = 5
max(5 6) = 6
max(6 6) = 6
... and so on
max(3 24) = 24
max(24 7) = 24
It's only slightly better than your answer

If exit array, enter from the other side

How can I do this for example if I have 1, 2, 3, 4, 5, 6, 7 array and I am in 4th position (number 5) and if you have to move it to the right 4 positions you should be in position 1 (number 2). The same goes with negative numbers but you move to left. I guess there is a need of while(true) loop?
Lets assume i is the index and n is the size of the array.
For positive i the needed index = i%n
For negative i i%n returns negative residue, so the needed index is n+i%n
You can use
int index(int i, int n) {
return i%n < 0 ? n + (i%n) : i%n;
}
You can calculate your index like this:
var newIndex = (index + 4) % 7;
So the fourth position becomes (4+4) % 7 or 1.
Always clearer with named functions and followable code path instead of voodoo one liners that work
public void MyTest()
{
var testData = new[] { 1, 2, 3, 4, 5, 6, 7 };
Assert.AreEqual(2, TraverseCircularArray(testData, 5, 3));
Assert.AreEqual(6, TraverseCircularArray(testData, 2, -4));
}
private int TraverseCircularArray(int[] array, int currentIndex, int interval)
{
var i = array[currentIndex];
if (currentIndex + interval < 0)
i = array[array.Length + (interval + currentIndex)];
else if (currentIndex + interval >= array.Length)
i = array[currentIndex - interval - 1];
else
i = array[currentIndex + interval];
return i;
}

Dividing up a long list of numbers and figuring out the minimum summation of each chunk

I have been working on three small programs that extract all the sub-strings of a given string (or even a list of integers) as well as all the different combinations of their elements. I now understand them...
My aim to start like this (originally) was to see if I can solve a puzzle, by learning these programs. Here is the puzzle:
Say I am trekking and I have 6 walking distances { 11, 16, 5, 5, 12, 10 } that I would like to finish within 3 days. So, I can do 11 and 16 kilometers during day 1, 5 and 5 kilometers during day 2, and finally 12 and 10 kilometers during day 3.
Perhaps I could do only 11 kilometers during day 1, 16 and 5 and 5 kilometers during day 2, and 12 and 10 kilometers during day 3.
etc . . . etc . . .
My goal is to work out the "minimum" walked distance over the course of these three days. So, in this example, 11 in day 1 and 26 in day 2 and 22 in day 3 would give a maximum of 26, and that 26 is actually the minimum - it does not get better than this.
No matter what combination of three chunks (days) I choose, the daily walked distance doe not get less than 26. For example, if I choose 11+16 for day 1 and 5+5 for day 2 and 12+10 for days 3, I am looking at a max of 27.
However, I cannot quite figure out how to divide up the list elements in 3, which is the number of days. If it was four, I could have four chunks with arbitrary number of distances in each day. And then add up all the divided elements and see which maximum comes out as minimum.
I appreciate this might be a too-big-a-bite for me at this point (I can just about understand the programs that I have put below) but I was wondering if someone perhaps could help me understand this and help me write a function that can handle any number of days and walking stages.
All I have been able to produce so far is a function that can print all the sub-lists and combinations of these 6 walking stages...
static void Main(string[] args)
{
string str = Console.ReadLine();
for (int i = 1; i <= str.Length; i++)
{
for (int j = 0; j <= (str.Length - i); j++)
{
string subStr = str.Substring(j, i);
Console.WriteLine(subStr);
}
}
Console.ReadLine();
}
static void Main(string[] args)
{
List<int> list = new List<int>() { 11, 16, 5, 5, 12, 10 };
for (int i = 0; i <= list.Count-1; i++)
{
for (int j = 0; j <= list.Count-i; j++)
{
string subList = string.Concat( list.GetRange(i, j) );
Console.WriteLine(subList);
}
}
Console.ReadLine();
}
static void Main(string[] args)
{
GetCombination( new List<int> { 11, 16, 5, 5, 12, 10 } );
Console.ReadLine();
}
static void GetCombination( List<int> list )
{
double count = Math.Pow(2, list.Count);
for (int i = 1; i <= (count-1); i++)
{
string str = Convert.ToString(i, 2).PadLeft(list.Count, '0');
for (int j = 0; j < str.Length; j++)
{
if ( str[j] == '1' )
{
Console.Write( list[j] );
}
}
Console.WriteLine();
}
}
This problem can be solved by dynamic programming. Here is my code for it with top-down approach:
class Program
{
static void Main(string[] args)
{
int[] array = { 11, 16, 5, 5, 12, 10 };
// change last parameter to the number or days
int min = MinDistance(array, 0, 0, 3);
Console.WriteLine(min);
}
static int MinDistance(int[] array, int day, int prevDayDistance, int daysLeft)
{
if (day == array.Length)
{
return prevDayDistance;
}
if (daysLeft == 0)
{
return int.MaxValue;
}
// Keep walking.
int keepWalkResult = MinDistance(array, day + 1, prevDayDistance + array[day], daysLeft);
// Postpone it to the next day.
int sleepResult = MinDistance(array, day, 0, daysLeft - 1);
// Choose the best solution.
return Math.Min(keepWalkResult, Math.Max(prevDayDistance, sleepResult));
}
}
For big input arrays you can consider caching MinDistance results for triples (day,prevDayDistance,daysLeft).

How to shift one array element wrap around?

I am trying to write a function which iterates through an array and when it finds a certain type of value it will shift it to the right a defined number of places.
I know how to shift elements by temporarily storing a value, shifting the right side elements to the left and then writing the temporary value in the correct place.
The bit I am struggling with is if the certain character appears near the end of the array I need it to wrap around and continue from the start of the array, so is circular.
So an array shifting, for example, capital letters to the right 3 places and special characters to the left 1 place:
{ M, y, N, a, m, e, P} becomes...
{ y, M, P, a, N, m, e}
To shift an element of 8 to the right 3 places I have below, but this only works if 8 appears earlier than 3 elements from the end of the array and will not wrap around.
input array:
{0, 1, 2, 3, 4, 5, 6, 7, **8**, 9}
desired output:
{0, **8**, 1, 2, 3, 4, 5, 6, 7, 9}
int[] array = new int[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
for (int i = array.Length - 1; i >= 0; i--)
{
if (array[i] == 8)
{
int temp = array[i];
int j = 0;
for (j = i; j < i + 3; j++)
{
array[j] = array[j + 1];
}
array[j] = temp;
}
}
Just use modulo arithmetic so that instead of writing to the element at index j as you shift, instead write to the element at index j % array.Length. Thusly:
public void FindAndShift<T>(T[] array, T value, int shift) {
int index = Array.IndexOf(array, value);
int shiftsRemaining = shift;
for(int currentPosition = index; shiftsRemaining > 0; shiftsRemaining--) {
array[currentPosition % array.Length] = array[(currentPosition + 1) % array.Length];
}
array[(index + shift) % array.Length] = value;
}
I have excluded error checking.
You can do it with an if statement, check if there is room enough before the end of the array and if it isn't you have to calculate how many steps to shift in the beginning of the array aswell.
I also think that you can do it by calculating the positions modulo the length of the array when you do the shifting, I can't try it at the moment but the logic in my head says that it should work.

Categories