Find next smallest value in array? - arrays

This question has been eating at me for a while. Basically, if you have an input array [4, 5, 2, 6, 7, 1], the next smallest number for 4 and 5 is 2, and for 6 and 7 is 1. I need to identify these smaller numbers. I have an obvious n^2 solution in time, but I feel there is an O(n) solution in time. I need to act on the presence of the next smallest number to the right, and also act in the case there is no smaller number to the right.
I've tried thinking of dynamic programming solutions and data structures (specifically a stack), but I can't seem to keep correctness and O(n) time complexity both in check, one or the other seems to fail for me.
Any help?

You can think of using a stack data structure for this. I have implemented it in Java. The idea is push the index to pop and while the top index value in stack is greater than current index value of the array pop the stack and assign the value at current index to the poped index location.
// Java Implementation of the idea
import java.util.Arrays;
import java.util.Stack;
public class NextSmallest{
public static void main(String[] args) {
int [] A = {4, 5, 2, 6, 7, 1};
int [] ret = nextSmallest(A);
System.out.println(Arrays.toString(ret)); // prints [2, 2, 1, 1, 1, 0]
}
static int [] nextSmallest(int [] A) {
Stack<Integer> stack = new Stack<>();
int n = A.length;
int [] nextSmallestIndex = new int[n];
for(int i = 0; i < n; i++) {
while(!stack.isEmpty() && A[stack.peek()] > A[i]) {
nextSmallestIndex[stack.pop()] = A[i];
}
stack.push(i);
}
return nextSmallestIndex;
}
}

You can use this simple loop over all array elements and get index of numbers you want
var arr = [4, 5, 2, 6, 7, 1];
var object = {};
for (var i = 0; i < arr.length; i++) {
if (i > 0 && i < arr.length - 1 && arr[i] < arr[i - 1] && arr[i] < arr[i + 1]) {
object[i] = arr[i];
} else if (i >= arr.length - 1 && arr[i] < arr[i - 1]) {
object[i] = arr[i];
}
}
console.log(object);
The object for output represents the index of next smallest number and its value. So if you want the smallest value for 4 or 5, because their indexes are before 2, their next smallest number will be object[2] and also for 6 and 7.
Full code
var arr = [4, 5, 2, 7, 6, 1];
var object = {};
for (var i = 0; i < arr.length; i++) {
if (i > 0 && i < arr.length - 1 && arr[i] < arr[i - 1] && arr[i] < arr[i + 1]) {
object[i] = arr[i];
} else if (i >= arr.length - 1 && arr[i] < arr[i - 1]) {
object[i] = arr[i];
}
}
function getResult(inpArr, number, obj) {
var keys = Object.keys(obj);
var index = inpArr.findIndex(function(itm) {
return itm == number;
});
// the number is not in the array
if (index == -1) {
return null;
}
for (var i = 0; i < keys.length; i++) {
if (index == keys[i]) {
return null;
}
if (index < keys[i]) {
return obj[keys[i]];
}
}
}
console.log("Result for 4: ", getResult(arr, 4, object));
console.log("Result for 5: ", getResult(arr, 5, object));
console.log("Result for 6: ", getResult(arr, 6, object));
console.log("Result for 7: ", getResult(arr, 7, object));
console.log("Result for 1: ", getResult(arr, 1, object));
console.log("Result for 2: ", getResult(arr, 2, object));

How do you define your start point? If you know you want to start at element 3 and look from there on, or do you want to find a value, and start at whatever element that value is at and go from there? What happens if a lower value isn't found for the rest of the array?
In PHP just because I'm in the middle of a PHP project, assuming you know what element you want to start with in the array.
<?php
// our array of numbers
$array=array(4, 5, 2, 7, 6, 1);
// what index are we starting at?
$start=2;
// what index are we comparing to?
$counter=0;
// some output
print("First value is ".$array[$start]." at array element ".$start);
// while the initial value is less or equal to the compare value, AND
// the compare position is within the bounds of the array
// increment the counter - our comparison isn't lower
while((($start+$counter)<count($array))&&($array[($start)]<=$array[($start+$counter)])){
$counter++;
}
// did we make it through without exceeding bounds of array or not?
if(($start+$counter)<count($array)){
print("\nNext lower value is ".$array[($start+$counter)]." at array element ".($start+$counter));
}else{
print("\nEnd of array reached without finding lower value...");
}
print("\n");
?>

Find the below solution in O(n) way with optimized code in JavaScript
var arr = [4, 5, 2, 7, 6, 1, 3, 4];
function getNextSmallestValue(index){
var elemvalue = arr[index];
var minValue = elemvalue;
for(var i=index;i<arr.length;i++){
if(minValue> arr[i]){
minValue = arr[i];
}
if((minValue!==elemvalue && elemvalue<arr[i]) || i === arr.length-1){
return minValue;
}
}
}
console.log(getNextSmallestValue(0)); // 2
console.log(getNextSmallestValue(3)); // 1

Related

In an array of numbers find higest product with specific multiple

The task was given an array of integers, find the maximum product between two numbers from the array, that is a multiple of 3.
</script>
arr = [-9, -11, 4, 6, 9, 7];
arr2 = [-11, 4, 6, 7];
arr3 = [11, 3, 5]
function findProduct(arr) {
let maxProduct = 0;
for(let i = 0; i < arr.length - 1; i++) {
for(let j = i + 1; j < arr.length; j++) {
let product = arr[i] * arr[j]
if(product % 3 !== 0) continue;
if(product > maxProduct) {
maxProduct = product
}
}
}
return maxProduct
}
console.log(findProduct(arr))
console.log(findProduct(arr2))
console.log(findProduct(arr3))
</script>
ยดยดยดยด
An O(N) time, O(1) extra space algorithm:
Traverse the array, keep track of two variables: max_multiple_of_three and min_multiple_of_three
Traverse the array, keep track of two variables: largest_number_in_array (which shouldn't have the same index as max_multiple of three) and smallest_number_in_array (which shouldn't have same index as min_multiple_of_three)
The answer will be either max_multiple_of_three * largest_number_in_array or min_multiple_of_three * smallest_number_in_array
Example 1:
arr = [-9, -11, 4, 6, 9, 7]
max_multiple_of_three = 9
min_multiple_of_three = -9
largest_number_in_array = 7
smallest_number_in_array = -11
ans = max(-9*-11, 9*7) = 99
Example 2:
arr = [-11, 4, 6, 7]
max_multiple_of_three = 6
min_multiple_of_three = 6
largest_number_in_array = 7
smallest_number_in_array = -11
ans = max(6*-11, 6*7) = 42

Count of strictly increasing sequence of integers

You are given two list of integers a and b of same length n, Find the count of strictly increasing sequences of integers
I[0] < I[1] < .. < I[n-1] such that min(a[i], b[i]) <= I[i] <= max(a[i], b[i]) for each i.
Eg.
a = [6,3,4,4]
b = [1,5,1,6]
Four possible solutions are possible
[1 3 4 5],
[1 3 4 6],
[2 3 4 5],
[2 3 4 6].
The length of both arrays will not exceed 100.
Each element is between 1 and 10000.```
Can someone provide a hint for this question? I am not able to figure out
You can use a dynamic programming approach here. The states of your DP will be the current index and last value ,like count_sequence(int index, int last_value) , loop through min(a[index], b[index]) to max(a[index], b[index]) ,if there is a value greater then last_value go to next index with current value like count_sequence(index+1, current_value), if you reach base case which is index>=n that means you find a sequence then return 1. Using this you can find every possible sequence.
With memorization, the complexity will be O(n*m),
n = array size, m = maximum element
JavaScript/node.js solution:
const a = [6, 3, 4, 4]
const b = [1, 5, 1, 6]
const n = a.length
let min = []
let max = []
for (let i = n - 1; i >= 0; i--) {
let itemMin = (min[i] = Math.min(a[i], b[i]))
let itemMax = (max[i] = Math.max(a[i], b[i]))
if (i > 0) {
const maxBefore = Math.max(a[i - 1], b[i - 1])
// max of before index, >= current min
if (maxBefore >= min[i]) {
itemMin = Math.min(maxBefore + 1, max[i])
}
}
if (i < n - 1) {
const minAfter = min[i + 1]
// min of after index, <= current or calculated min
if (itemMin >= minAfter) {
itemMin = Math.min(minAfter - 1, min[i])
}
// max correction
itemMax = Math.min(max[i], minAfter - 1)
}
// Test is solution possible, if not do something
if (itemMin < min[i] || itemMin > max[i]) {
throw new Error('Impossible to solve...')
}
if (itemMax < min[i] || itemMax > max[i]) {
throw new Error('Impossible to solve...')
}
// Set min and max values
min[i] = itemMin
max[i] = itemMax
}
// ***** Printing results
function printResult(min, max, str = '', item = 0) {
const n = min.length
for (let j = min[item]; j <= max[item]; j++) {
if (item < n - 1) {
printResult(min, max, `${item !== 0 ? str : ''}${j},`, item + 1)
} else {
console.log(`[${str}${j}]`)
}
}
}
printResult(min, max)
Given two arrays, one holding the min value and the other the max value for each index, you could define a simple recursive function to derive each possible increasing sequence, with the starting value at each position being the maximum of the current min value and the previously selected value plus 1.
Here's some Java code to illustrate:
static void incSeq(int[] min, int[] max, int[] res, int pos, int prev)
{
if(pos == min.length)
{
System.out.println("seq: " + Arrays.toString(res));
return;
}
for(int j = Math.max(prev+1, min[pos]); j <= max[pos]; j++)
{
res[pos] = j;
incSeq(min, max, res, pos+1, j);
}
}
However, if we consider input such as:
min = {1, 1, 1, 1}
max = {100, 100, 100, 5}
we can see that our function is going to do a lot of useless work iterating through values in the first three positions that will not be part of an increasing sequence.
We can fix this by recognizing that the maximum value we need to consider for position i is one less that the max value at position i+1. If we start at the last position and work backwards using this rule we can update the max array above to:
max = {2, 3, 4, 5}
Which will mean a lot less work for our recursive function.
Here's the complete code:
public static void main(String[] args)
{
int n = 4;
int[] a = {6,3,4,4};
int[] b = {1,5,1,6};
int[] min = new int[n];
int[] max = new int[n];
System.out.println("a: " + Arrays.toString(a));
System.out.println("b: " + Arrays.toString(b));
for(int i=0; i<n; i++)
{
min[i] = Math.min(a[i], b[i]);
max[i] = Math.max(a[i], b[i]);
}
System.out.println("min: " + Arrays.toString(min));
System.out.println("max: " + Arrays.toString(max));
// cap max values
for(int i=n-1; i>0; i--)
{
max[i-1] = Math.min(max[i-1], max[i]-1);
}
System.out.println("max: " + Arrays.toString(max) + "\n");
incSeq(min, max, new int[n], 0, 0);
}
static void incSeq(int[] min, int[] max, int[] res, int pos, int prev)
{
if(pos == min.length)
{
System.out.println("seq: " + Arrays.toString(res));
return;
}
for(int j = Math.max(prev+1, min[pos]); j <= max[pos]; j++)
{
res[pos] = j;
incSeq(min, max, res, pos+1, j);
}
}
Output:
a: [6, 3, 4, 4]
b: [1, 5, 1, 6]
min: [1, 3, 1, 4]
max: [6, 5, 4, 6]
max: [2, 3, 4, 6]
seq: [1, 3, 4, 5]
seq: [1, 3, 4, 6]
seq: [2, 3, 4, 5]
seq: [2, 3, 4, 6]

Loop works on one array but same loop does not work on different array - why?

Beginner here! Working through some basic Javascript challenges:
I have these two arrays:
var problem = [29.50, 35.50, 18.50, 38.00, 42.50, 47.50];
var numbers = [10, 5, 22, 100, 15, 30];
I'm trying to sort from lowest number to highest. Below is my sort function; it seems to work perfectly on the second one, but it does not work on the first one. Why is this?
function sorter(array) {
var swap, done = false,
swapped;
while (!done){
swapped = 0;
for(i = 1; i < array.length; i++) {
if (array[i - 1] > array[i]) {
swap = array[i];
array[i] = array[i - 1];
array[i - 1] = swap;
swapped = 1;
};
if (swapped == 0) {
done = true;
}
};
};
return array;
};
My output for console.log(sorter(problem)); is :
[29.5, 18.5, 35.5, 38, 42.5, 47.5]
Why aren't the first two numbers swapped?
My output for console.log(sorter(numbers)); is:
[5, 10, 15, 22, 30, 100]

Google Kick Start Time Limited on Dart

I found out that my code Time Limited, but algorithm is just fine i believe. Is it my code problem or language?
Here is the task: Task src
An arithmetic array is an array that contains at least two integers and the differences between consecutive integers are equal. For example, [9, 10], [3, 3, 3], and [9, 7, 5, 3] are arithmetic arrays, while [1, 3, 3, 7], [2, 1, 2], and [1, 2, 4] are not arithmetic arrays.
Sarasvati has an array of N non-negative integers. The i-th integer of the array is Ai. She wants to choose a contiguous arithmetic subarray from her array that has the maximum length. Please help her to determine the length of the longest contiguous arithmetic subarray.
import 'dart:io';
import 'dart:math';
foo (array){
var diff = [];
var size = 2;
var answ = 2;
for (int i = 0; i < array.length - 1; i++){
diff.add(array[i + 1] - array[i]);
}
for (int i = 1; i < diff.length; i++){
if (diff[i] == diff[i - 1]){
size++;
}
else{
size = 2;
}
answ = max(answ, size);
}
return answ;
}
void main() {
var N = int.parse(stdin.readLineSync());
for (int i = 0; i < N; i++){
var M = int.parse(stdin.readLineSync());
String s = stdin.readLineSync();
var intArray = [];
s.trim().split(" ").forEach((x) => intArray.add(int.parse(x)));
print("Case #${i + 1}: ${foo(intArray)}");
}
}

How to generate all subsequence of even length from an array?

I am dealing with a problem and that problem requires the answer to this as a subroutine. I know how to generate all subsequences from an array using bit manipulation but struggling to generate subsequences of even length.
For the sake of example, assume that there is an array A = [2, 5, 4, 2, 3, 1]
I want all the subsequences of even length i.e., of length 2, 4, and 6.
Edit 1: 1<=N<=1000 where N is the size of the array.
Since you already know how to generate all subsequences, then just remove the last element and generate all subsequences of the remaining array, but append the last back to each subsequence with an odd length.
Easy to prove that this generates all the even-length subsequences:
Every even-length subsequence of A that does not end in the last element of A, is an even-length subsequence of the earlier elements.
Every even-length subsequence of A that does end in the last element of A, has that element preceded by an odd-length subsequence of the earlier elements.
Subarrays
Using generator functions, you can take advantage of deferred execution to iterate all of the even-lengthed subarrays without retaining the entire collection of subarrays in memory:
function * subarrays (array) {
for (let length = 1; length <= array.length; length++) {
for (let index = 0; index + length <= array.length; index++) {
yield array.slice(index, index + length);
}
}
}
const filter = predicate => function * (iterator) {
for (const value of iterator) {
if (predicate(value)) yield value;
}
};
const even = filter(subarray => subarray.length % 2 === 0);
for (const subarray of even(subarrays ([2, 5, 4, 2, 3, 1]))) {
console.log(subarray.join());
}
However, if you do want the entire collection of even-lengthed subarrays, you can use Array.from() to consume the iterator and populate an array of subarrays:
function * subarrays (array) {
for (let length = 1; length <= array.length; length++) {
for (let index = 0; index + length <= array.length; index++) {
yield array.slice(index, index + length);
}
}
}
const filter = predicate => function * (iterator) {
for (const value of iterator) {
if (predicate(value)) yield value;
}
};
const even = filter(subarray => subarray.length % 2 === 0);
const result = Array.from(even(subarrays([2, 5, 4, 2, 3, 1])));
console.log(JSON.stringify(result));
Subsequences
To iterate all even-lengthed subsequences, one of the easiest methods is to keep a lookup table of which values to filter() from the array. We can achieve this with fairly minimal memory overhead by leveraging a Uint32Array:
function _increment (uint32Array) {
for (let index = 0; index < uint32Array.length; index++) {
// use unsigned integer overflow to
// perform carry in base 2**32 addition
if (++uint32Array[index]) return;
}
}
function * subsequences (array) {
const lut = new Uint32Array(Math.ceil(array.length / 32));
let subsequence;
while (true) {
yield subsequence = array.filter(
(_, index) => (lut[index >>> 5] >>> (index % 32)) & 1
);
if (subsequence.length === array.length) return;
_increment(lut);
}
}
const filter = predicate => function * (iterator) {
for (const value of iterator) {
if (predicate(value)) yield value;
}
};
const even = filter(({ length }) => (length > 0) && (length % 2 === 0));
for (const subsequence of even(subsequences([2, 5, 4, 2, 3, 1]))) {
console.log(subsequence.join());
}
#include <stdio.h>
#define N 4
const int A[] = { 2, 5, 4, 2, 3, 1, -1 };
int out[1000];
void gen(const int *p, int *pout) {
if(pout - out < N) {
while((*pout = *p++) > 0)
gen(p, pout + 1);
} else { // print output
for(const int *o = out; o < pout; o++)
printf("%d ", *o);
putchar('\n');
}
}
int main(int argc, char **argv) {
gen(A, out);
return 0;
}
Here's Python, which is as good as pseudocode:
def even_subsequences(L):
# yield the empty subsequence
yield []
# iterate over subsequence starting points
for i in range(len(L)):
# subsequence end point is the starting point plus an even number
for j in range(i+2, len(L)+1, 2):
# slice the list
yield L[i:j]
>>> list(even_subsequences([1,2,3,4,5,6]))
[[],
[1, 2],
[1, 2, 3, 4],
[1, 2, 3, 4, 5, 6],
[2, 3],
[2, 3, 4, 5],
[3, 4],
[3, 4, 5, 6],
[4, 5],
[5, 6]]

Resources