Coin Change Leetcode - arrays

Problem: https://leetcode.com/problems/coin-change/
Solution:
https://repl.it/#Stylebender/HatefulAliceblueTransversal#index.js
var coinChange = function(coins, amount) {
let dp = Array(amount + 1).fill(Infinity); //Fill dp array with dummy values
dp[0] = 0;
for (let i = 1; i <= amount; i++) {
for (let j = 0; j < coins.length; j++) { //Iterate through coin denominations
if (coins[j] <= i) { //Is current coin denomination less than amount?
dp[i] = Math.min(dp[i], 1 + dp[i - coins[j]]);
//dp array[current amount - coin denomination]
}
}
}
return dp[amount] === Infinity ? -1 : dp[amount];
};
I understand the general conceptual flow of the solution of building the dp array from button up but I was just wondering with respect to Line 10:
dp[i] = Math.min(dp[i], 1 + dp[i - coins[j]]);
Why is there a 1 + when you select the current j'th coin denomination for consideration?
Is it because since there is a valid coin denomination, we have unlocked a new method to make up the i'th amount?

Yes, that's right. We'd be approaching the target amount by that one increment.
If for instance 0.5 would be somehow the min increment, then that would have become 0.5 + the rest.
const coinChange = function(coins, amount) {
const inf = Math.pow(2, 31)
const dp = []
dp[0] = 0
while (dp.length <= amount) {
let curr = inf - 1
for (let index = 0; index < coins.length; index++) {
if (dp.length - coins[index] < 0) {
continue
}
curr = Math.min(curr, 1 + dp[dp.length - coins[index]])
}
dp.push(curr)
}
return dp[amount] == inf - 1 ? -1 : dp[amount]
};
Maybe it would be easier to grasp in Python:
class Solution:
def coinChange(self, coins, amount):
dp = [0] + [float('inf')] * amount
for index in range(1, amount + 1):
for coin in coins:
if index - coin > -1:
dp[index] = min(dp[index], dp[index - coin] + 1)
return -1 if dp[-1] == float('inf') else dp[-1]

Related

Search unsorted array for 3 elements which sum to a value

I am trying to make an algorithm, of Θ( n² ).
It accepts an unsorted array of n elements, and an integer z,
and has to return 3 indices of 3 different elements a,b,c ; so a+b+c = z.
(return NILL if no such integers were found)
I tried to sort the array first, in two ways, and then to search the sorted array.
but since I need a specific running time for the rest of the algorithm, I am getting lost.
Is there any way to do it without sorting? (I guess it does have to be sorted) either with or without sorting would be good.
example:
for this array : 1, 3, 4, 2, 6, 7, 9 and the integer 6
It has to return: 0, 1, 3
because ( 1+3+2 = 6)
Algorithm
Sort - O(nlogn)
for i=0... n-1 - O(1) assigning value to i
new_z = z-array[i] this value is updated each iteration. Now, search for new_z using two pointers, at begin (index 0) and end (index n-1) If sum (array[ptr_begin] + array[ptr_ens]) is greater then new_z, subtract 1 from the pointer at top. If smaller, add 1 to begin pointer. Otherwise return i, current positions of end and begin. - O(n)
jump to step 2 - O(1)
Steps 2, 3 and 4 cost O(n^2). Overall, O(n^2)
C++ code
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> vec = {3, 1, 4, 2, 9, 7, 6};
std::sort(vec.begin(), vec.end());
int z = 6;
int no_success = 1;
//std::for_each(vec.begin(), vec.end(), [](auto const &it) { std::cout << it << std::endl;});
for (int i = 0; i < vec.size() && no_success; i++)
{
int begin_ptr = 0;
int end_ptr = vec.size()-1;
int new_z = z-vec[i];
while (end_ptr > begin_ptr)
{
if(begin_ptr == i)
begin_ptr++;
if (end_ptr == i)
end_ptr--;
if ((vec[begin_ptr] + vec[end_ptr]) > new_z)
end_ptr--;
else if ((vec[begin_ptr] + vec[end_ptr]) < new_z)
begin_ptr++;
else {
std::cout << "indices are: " << end_ptr << ", " << begin_ptr << ", " << i << std::endl;
no_success = 0;
break;
}
}
}
return 0;
}
Beware, result is the sorted indices. You can maintain the original array, and then search for the values corresponding to the sorted array. (3 times O(n))
The solution for the 3 elements which sum to a value (say v) can be done in O(n^2), where n is the length of the array, as follows:
Sort the given array. [ O(nlogn) ]
Fix the first element , say e1. (iterating from i = 0 to n - 1)
Now we have to find the sum of 2 elements sum to a value (v - e1) in range from i + 1 to n - 1. We can solve this sub-problem in O(n) time complexity using two pointers where left pointer will be pointing at i + 1 and right pointer will be pointing at n - 1 at the beginning. Now we will move our pointers either from left or right depending upon the total current sum is greater than or less than required sum.
So, overall time complexity of the solution will be O(n ^ 2).
Update:
I attached solution in c++ for the reference: (also, added comments to explain time complexity).
vector<int> sumOfthreeElements(vector<int>& ar, int v) {
sort(ar.begin(), ar.end());
int n = ar.size();
for(int i = 0; i < n - 2 ; ++i){ //outer loop runs `n` times
//for every outer loop inner loops runs upto `n` times
//therefore, overall time complexity is O(n^2).
int lo = i + 1;
int hi = n - 1;
int required_sum = v - ar[i];
while(lo < hi) {
int current_sum = ar[lo] + ar[hi];
if(current_sum == required_sum) {
return {i, lo, hi};
} else if(current_sum > required_sum){
hi--;
}else lo++;
}
}
return {};
}
I guess this is similar to LeetCode 15 and 16:
LeetCode 16
Python
class Solution:
def threeSumClosest(self, nums, target):
nums.sort()
closest = nums[0] + nums[1] + nums[2]
for i in range(len(nums) - 2):
j = -~i
k = len(nums) - 1
while j < k:
summation = nums[i] + nums[j] + nums[k]
if summation == target:
return summation
if abs(summation - target) < abs(closest - target):
closest = summation
if summation < target:
j += 1
elif summation > target:
k -= 1
return closest
Java
class Solution {
public int threeSumClosest(int[] nums, int target) {
Arrays.sort(nums);
int closest = nums[0] + nums[nums.length >> 1] + nums[nums.length - 1];
for (int first = 0; first < nums.length - 2; first++) {
int second = -~first;
int third = nums.length - 1;
while (second < third) {
int sum = nums[first] + nums[second] + nums[third];
if (sum > target)
third--;
else
second++;
if (Math.abs(sum - target) < Math.abs(closest - target))
closest = sum;
}
}
return closest;
}
}
LeetCode 15
Python
class Solution:
def threeSum(self, nums):
res = []
nums.sort()
for i in range(len(nums) - 2):
if i > 0 and nums[i] == nums[i - 1]:
continue
lo, hi = -~i, len(nums) - 1
while lo < hi:
tsum = nums[i] + nums[lo] + nums[hi]
if tsum < 0:
lo += 1
if tsum > 0:
hi -= 1
if tsum == 0:
res.append((nums[i], nums[lo], nums[hi]))
while lo < hi and nums[lo] == nums[-~lo]:
lo += 1
while lo < hi and nums[hi] == nums[hi - 1]:
hi -= 1
lo += 1
hi -= 1
return res
Java
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> res = new LinkedList<>();
for (int i = 0; i < nums.length - 2; i++) {
if (i == 0 || (i > 0 && nums[i] != nums[i - 1])) {
int lo = -~i, hi = nums.length - 1, sum = 0 - nums[i];
while (lo < hi) {
if (nums[lo] + nums[hi] == sum) {
res.add(Arrays.asList(nums[i], nums[lo], nums[hi]));
while (lo < hi && nums[lo] == nums[-~lo])
lo++;
while (lo < hi && nums[hi] == nums[hi - 1])
hi--;
lo++;
hi--;
} else if (nums[lo] + nums[hi] < sum) {
lo++;
} else {
hi--;
}
}
}
}
return res;
}
}
Reference
You can see the explanations in the following links:
LeetCode 15 - Discussion Board
LeetCode 16 - Discussion Board
LeetCode 15 - Solution
You can use something like:
def find_3sum_restr(items, z):
# : find possible items to consider -- O(n)
candidates = []
min_item = items[0]
for i, item in enumerate(items):
if item < z:
candidates.append(i)
if item < min_item:
min_item = item
# : find possible couples to consider -- O(n²)
candidates2 = []
for k, i in enumerate(candidates):
for j in candidates[k:]:
if items[i] + items[j] <= z - min_item:
candidates2.append([i, j])
# : find the matching items -- O(n³)
for i, j in candidates2:
for k in candidates:
if items[i] + items[j] + items[k] == z:
return i, j, k
This O(n + n² + n³), hence O(n³).
While this is reasonably fast for randomly distributed inputs (perhaps O(n²)?), unfortunately, in the worst case (e.g. for an array of all ones, with a z > 3), this is no better than the naive approach:
def find_3sum_naive(items, z):
n = len(items)
for i in range(n):
for j in range(i, n):
for k in range(j, n):
if items[i] + items[j] + items[k] == z:
return i, j, k

Pattern for action decision

I am writing maze generator and at the some point I have to choose random unvisited neighbour of a cell. The first idea was just to enumerate neighbours such as left = 0, top = 1, right = 2, bottom = 3 and use rand() % 4 to generate random number and choose appropriate cell. However, not all cells features 4 neighbours, so that I had to write following code:
Cell* getRandomNeighbour(const Maze* const maze, const Cell* const currentCell) {
int randomNumb = rand() % 4;
int timer = 1;
while(timer > 0) {
if (randomNumb == 0 && currentCell->x < maze->width-1 && maze->map[currentCell->y][currentCell->x+1].isUnvisited)
return &maze->map[currentCell->y][currentCell->x+1];
if (randomNumb == 1 && currentCell->x > 0 && maze->map[currentCell->y][currentCell->x-1].isUnvisited)
return &maze->map[currentCell->y][currentCell->x-1];
if (randomNumb == 2 && currentCell->y < maze->height-1 && maze->map[currentCell->y+1][currentCell->x].isUnvisited)
return &maze->map[currentCell->y+1][currentCell->x];
if (randomNumb == 3 && currentCell->y > 0 && maze->map[currentCell->y-1][currentCell->x].isUnvisited)
return &maze->map[currentCell->y-1][currentCell->x];
timer--;
randomNumb = rand() % 4;
}
if (currentCell->x < maze->width-1 && maze->map[currentCell->y][currentCell->x+1].isUnvisited)
return &maze->map[currentCell->y][currentCell->x+1];
if (currentCell->x > 0 && maze->map[currentCell->y][currentCell->x-1].isUnvisited)
return &maze->map[currentCell->y][currentCell->x-1];
if (currentCell->y < maze->height-1 && maze->map[currentCell->y+1][currentCell->x].isUnvisited)
return &maze->map[currentCell->y+1][currentCell->x];
if (currentCell->y > 0 && maze->map[currentCell->y-1][currentCell->x].isUnvisited)
return &maze->map[currentCell->y-1][currentCell->x];
return NULL;
}
So, if after 10 iterations the right decision isn't chosen, it will be picked by brute force. This approach seems to be good for the reason that varying of variable timer changes the complexity of maze: the less timer is, the more straightforward maze is. Nevertheless, if my only purpose is to generate completely random maze, it takes a lot of execution time and look a little bit ugly. Is there any pattern(in C language) or way of refactoring that could enable me to deal with this situation without long switches and a lot of if-else constructions?
As #pat and #Ivan Gritsenko suggested, you can limit your random choice to the valid cells only, like this:
Cell* getRandomNeighbour(const Maze* const maze, const Cell* const currentCell)
{
Cell *neighbours[4] = {NULL};
int count = 0;
// first select the valid neighbours
if ( currentCell->x < maze->width - 1
&& maze->map[currentCell->y][currentCell->x + 1].isUnvisited ) {
neighbours[count++] = &maze->map[currentCell->y][currentCell->x + 1];
}
if ( currentCell->x > 0
&& maze->map[currentCell->y][currentCell->x - 1].isUnvisited ) {
neighbours[count++] = &maze->map[currentCell->y][currentCell->x - 1];
}
if ( currentCell->y < maze->height - 1
&& maze->map[currentCell->y + 1][currentCell->x].isUnvisited ) {
neighbours[count++] = &maze->map[currentCell->y + 1][currentCell->x];
}
if ( currentCell->y > 0
&& maze->map[currentCell->y - 1][currentCell->x].isUnvisited ) {
neighbours[count++] = &maze->map[currentCell->y - 1][currentCell->x];
}
// then choose one of them (if any)
int chosen = 0;
if ( count > 1 )
{
int divisor = RAND_MAX / count;
do {
chosen = rand() / divisor;
} while (chosen >= count);
}
return neighbours[chosen];
}
The rationale behind the random number generation part (as opposed to the more common rand() % count) is well explained in this answer.
Factoring repeated code, and a more disciplined way of picking the order of directions to try yields this:
// in_maze returns whether x, y is a valid maze coodinate.
int in_maze(const Maze* const maze, int x, int y) {
return 0 <= x && x < maze->width && 0 <= y && y < maze->height;
}
Cell *get_random_neighbour(const Maze* const maze, const Cell* const c) {
int dirs[] = {0, 1, 2, 3};
// Randomly shuffle dirs.
for (int i = 0; i < 4; i++) {
int r = i + rand() % (4 - i);
int t = dirs[i];
dirs[i] = dirs[r];
dirs[r] = t;
}
// Iterate through the shuffled dirs, returning the first one that's valid.
for (int trial=0; trial<4; trial++) {
int dx = (dirs[trial] == 0) - (dirs[trial] == 2);
int dy = (dirs[trial] == 1) - (dirs[trial] == 3);
if (in_maze(maze, c->x + dx, c->y + dy)) {
const Cell * const ret = &maze->map[c->y + dy][c->x + dx];
if (ret->isUnvisited) return ret;
}
}
return NULL;
}
(Disclaimer: untested -- it probably has a few minor issues, for example const correctness).

find any increase sub-sequence with size 3 in an un-ordered array

I've encountered a question online: find any increase sub-sequence with size 3 in an un-ordered array using O(n) time complexity. (just need to return one valid result)
For example:
1 2 0 3 ==> 1 2 3
2 4 7 8 ==> 2 4 7; 4 7 8; 2 4 8 (anyone of them is Okay)
This one is pretty relative to the longest increase sub-sequence. But it is also very specific: we just want size 3. I came out an O(N) solution which requires to scan the array twice.
The idea:
(1) For each element, find is there any one smaller than it on the left side, is there any one larger than it on the right side.
(2) We can compute a minimum pre-array and a maximum post-array as pre-processing. For example:
1 2 0 3 ==> minimum pre-array: none 1 1 0
1 2 0 3 ==> maximum post-array: 3 3 3 None
I'm wondering is there any other solutions for this one?
Did you try looking a cs.stackexchange?
It has already been solved there: https://cs.stackexchange.com/questions/1071/is-there-an-algorithm-which-finds-sorted-subsequences-of-size-three-in-on-ti
One idea is to do something like longest increasing subsequence algorithm, and does it in one pass.
There are multiple solutions in that question I linked.
Here's the solution the question refers to (in JavaScript)
The comments http://www.geeksforgeeks.org/find-a-sorted-subsequence-of-size-3-in-linear-time/ have other alternative solutions.
function findIncSeq3(arr) {
var hi = Array(arr.length);
var lo = Array(arr.length);
hi[arr.length - 1] = lo[0] = null;
var tmp, i;
for (i = arr.length - 2, tmp = arr.length - 1; i >= 0; i--) {
if (arr[i] >= arr[tmp]) {
tmp = i;
hi[i] = null;
} else {
hi[i] = tmp;
}
}
for (i = 1, tmp = 0; i < arr.length; i++) {
if (arr[i] <= arr[tmp]) {
tmp = i;
lo[i] = null;
} else {
lo[i] = tmp;
}
}
for(i = 0; i < arr.length; i++) {
if(hi[i] !== null && lo[i] != null) {
return [arr[lo[i]], arr[i], arr[hi[i]]];
}
}
return null;
}
console.log("1,2,5", findIncSeq3([1, 2, 0, 5]));
console.log("null", findIncSeq3([5, 4, 3, 2, 1]));
console.log("2,3,9", findIncSeq3([10, 8, 6, 4, 2, 5, 3, 9]));
EDIT Here's a single iteration version.
function findIncSeq3(arr) {
var tmp = Array(arr.length);
for(var i = 0, s = arr.length - 1, lo = 0, hi = arr.length -1; i <= s; i++) {
if(s - i !== hi) {
if(arr[s - i] >= arr[hi]) {
hi = s - i;
} else if(tmp[s - i] !== undefined) {
return [arr[tmp[s - i]], arr[s - i], arr[hi]];
} else {
tmp[s - i] = hi;
}
}
if(i !== lo) {
if(arr[i] <= arr[lo]) {
lo = i;
} else if(tmp[i] !== undefined) {
return [arr[lo], arr[i], arr[tmp[i]]];
} else {
tmp[i] = lo;
}
}
}
return null;
}

generating random numbers without repeating with an exception AS3

I have seen this question for other languages but not for AS3... and I'm having a hard time understanding it...
I need to generate 3 numbers, randomly, from 0 to 2, but they cannot repeat (as in 000, 001, 222, 212 etc) and they cannot be in the correct order (0,1,2)...
Im using
for (var u: int = 0; u < 3; u++)
{
mcCor = new CorDaCarta();
mcCor.x = larguraTrio + (mcCor.width + 5) * (u % 3);
mcCor.y = alturaTrio + (mcCor.height + 5) * (Math.floor(u / 3));
mcCor.gotoAndStop((Math.random() * (2 - u + 1) + u) | 0); // random w/ repeats
//mcCor.gotoAndStop(Math.floor(Math.random() * (2 - u + 1) + u)); // random w/ repeats
//mcCor.gotoAndStop((Math.random() * 3) | 0); // crap....
//mcCor.gotoAndStop(Math.round(Math.random()*u)); // 1,1,1
//mcCor.gotoAndStop(u + 1); // 1,2,3
mcCor.buttonMode = true;
mcCor.addEventListener(MouseEvent.CLICK, cliquetrio);
mcExplic.addChild(mcCor);
trio.push(mcCor);
}
those are the codes i've been trying.... best one so far is the active one (without the //), but it still gives me duplicates (as 1,1,1) and still has a small chance to come 0,1,2....
BTW, what I want is to mcCor to gotoAndStop on frames 1, 2 or 3....without repeating, so THE USER can put it on the right order (1,2,3 or (u= 0,1,2), thats why I add + 1 sometimes there)
any thoughts?? =)
I've found that one way to ensure random, unique numbers is to store the possible numbers in an array, and then sort them using a "random" sort:
// store the numbers 0, 1, 2 in an array
var sortedNumbers:Array = [];
for(var i:int = 0; i < 3; i++)
{
sortedNumbers.push(i);
}
var unsortedNumbers:Array = sortedNumbers.slice(); // make a copy of the sorted numbers
trace(sortedNumbers); // 0,1,2
trace(unsortedNumbers); // 0,1,2
// randomly sort array until it no longer matches the sorted array
while(sortedNumbers.join() == unsortedNumbers.join())
{
unsortedNumbers.sort(function (a:int, b:int):int { return Math.random() > .5 ? -1 : 1; });
}
trace(unsortedNumbers); // [1,0,2], [2,1,0], [0,1,2], etc
for (var u: int = 0; u < 3; u++)
{
mcCor = new CorDaCarta();
mcCor.x = larguraTrio + (mcCor.width + 5) * (u % 3);
mcCor.y = alturaTrio + (mcCor.height + 5) * (Math.floor(u / 3));
// grab the corresponding value from the unsorted array
mcCor.gotoAndStop(unsortedNumbers[u] + 1);
mcCor.buttonMode = true;
mcCor.addEventListener(MouseEvent.CLICK, cliquetrio);
mcExplic.addChild(mcCor);
trio.push(mcCor);
}
Marcela is right. Approach with an Array is widely used for such task. Of course, you will need to check 0, 1, 2 sequence and this will be ugly, but in common code to get the random sequence of integers can look like this:
function getRandomSequence(min:int, max:int):Array
{
if (min > max) throw new Error("Max value should be greater than Min value!");
if (min == max) return [min];
var values:Array = [];
for (var i:int = min; i <= max; i++) values.push(i);
var result:Array = [];
while (values.length > 0) result = result.concat(values.splice(Math.floor(Math.random() * values.length), 1));
return result;
}
for (var i:uint = 0; i < 10; i++)
{
trace(getRandomSequence(1, 10));
}
You will get something like that:
2,9,3,8,10,6,5,1,4,7
6,1,2,4,8,9,5,10,7,3
3,9,10,6,8,2,5,4,1,7
7,6,1,4,3,8,9,2,10,5
4,6,7,1,3,2,9,10,8,5
3,10,5,9,1,7,2,4,8,6
1,7,9,6,10,3,4,5,2,8
4,10,8,9,3,2,6,1,7,5
1,7,8,9,10,6,4,3,2,5
7,5,4,2,8,6,10,3,9,1
I created this for you. It is working but it can be optimized...
Hope is good for you.
var arr : Array = [];
var r : int;
for (var i: int = 0; i < 3; i++){
r=rand(0,2);
if(i == 1){
if(arr[0] == r){
i--;
continue;
}
if(arr[0] == 0){
if(r==1){
i--;
continue;
}
}
}else if(i==2){
if(arr[0] == r || arr[1] == r){
i--;
continue;
}
}
arr[i] = r;
}
trace(arr);
for(var i=0;i<3;i++){
mcCor = new CorDaCarta();
mcCor.x = larguraTrio + (mcCor.width + 5) * (i % 3);
mcCor.y = alturaTrio + (mcCor.height + 5) * (Math.floor(i / 3));
mcCor.gotoAndStop(arr[i]);
mcCor.buttonMode = true;
mcCor.addEventListener(MouseEvent.CLICK, cliquetrio);
mcExplic.addChild(mcCor);
trio.push(mcCor);
}
function rand(min:int, max:int):int {
return Math.round(Math.random() * (max - min) + min);
}
try this...

Find the Ninja Index of an array

It is an interesting puzzle I came across , according to which , given an array , we need to find the ninja index in it.
A Ninja index is defined by these rules :
An index K such that all elements with smaller indexes have values lower or equal to A[K] and all elements with greater indexes have values greater or equal to A[K].
For example , consider :
A[0]=4, A[1]=2, A[2]=2, A[3]=3, A[4]=1, A[5]=4, A[6]=7, A[7]=8, A[8]=6, A[9]=9.
In this case, 5 is a ninja index , since A[r]<=A[5] for r = [0,k] and A[5]<=A[r] r = [k,n].
What algorithm shall we follow to find it in O(n) . I already have a brute force O(n^2) solution.
EDIT : There can be more than 1 ninja index , but we need to find the first one preferably. And in case there is no NI , then we shall return -1.
Precompute minimum values for all the suffixes of the array and maximum values for all prefixes. With this data every element can be checked for Ninja in O(1).
A python solution that will take O(3n) operations
def n_index1(a):
max_i = []
maxx = a[0]
for j in range(len(a)):
i=a[j]
if maxx<=i and j!=0:
maxx=i
max_i.append(1)
else:
max_i.append(-1)
return max_i
def n_index2(a):
max_i = []
maxx = -a[len(a)-1]
for j in range(len(a)-1,-1,-1):
i=-a[j] # mind the minus
if maxx<=i and j!=len(a)-1:
maxx=i
max_i.append(1)
else:
max_i.append(-1)
return max_i
def parse_both(a,b):
for i in range(len(a)):
if a[i]==1 and b[len(b)-1-i]==1:
return i
return -1
def ninja_index(v):
a = n_index1(v)
b = n_index2(v)
return parse_both(a,b)
Another Python solution, following the same general approach. Maybe a bit shorter.
def ninja(lst):
maxs = lst[::]
mins = lst[::]
for i in range(1, len(lst)):
maxs[ i] = max(maxs[ i], maxs[ i-1])
mins[-1-i] = min(mins[-1-i], mins[-i ])
return [i for i in range(len(lst)) if maxs[i] <= lst[i] <= mins[i]]
I guess it could be optimized a bit w.r.t that list-copying-action, but this way it's more concise.
This straight-forward Java code calculates leftmost index that has property "all elements rightwards are not lesser":
private static int fwd(int[] a) {
int i = -1;
for (int j = 0; j < a.length - 1; j++) {
if (a[j + 1] >= a[j] && i == -1) {
i = j + 1;
} else if (i != -1 && a[j + 1] < a[i]) {
i = -1;
}
}
return i;
}
Almost same code calculates leftmost index that has property "all elements leftwards are not greater":
private static int bwd(int[] a) {
int i = -1;
for (int j = 0; j < a.length - 1; j++) {
if (a[j + 1] >= a[j] && i == -1) {
i = j + 1;
} else if (i != -1 && a[j + 1] < a[i]) {
i = -1;
}
}
return i;
}
If results are the same, leftmost Ninja index is found.

Resources