How to generate row-wise permutations of a 2d Array? - algorithm

I recently got this question (paraphrased below) in a practice interview test and it still stumps me:
Given a 2d array A, generate a list of row-wise 1d array permutations from it.
A = [
[1],
[5, 2],
[6]
]
Answer: [[1, 5, 2, 6], [1, 6, 5, 2], [5, 2, 1, 6], [5, 2, 6, 1], [6, 1, 5, 2], [6, 5, 2, 1]]
Explanation of answer: We are permuting on the rows, so it's like generating permutations for [a,b,c] where each of these elements is a 1d array of potentially varying length.
I'm sure the solution involves backtracking, but anytime I try to implement it I end up with a 5+ parameters. I was hoping one of you folks could kindly provide an elegant solution, pseudocode, or explanation.

You're really just permuting the row order, and then flattening the matrix for each permutation. Python example:
from itertools import chain, permutations
def flatten(matrix):
return list(chain(*matrix))
def permute(matrix):
return [flatten(perm) for perm in permutations(matrix)]
With your example:
>>> M = [[1], [5, 2], [6]]
>>> permute(M)
[[1, 5, 2, 6], [1, 6, 5, 2], [5, 2, 1, 6], [5, 2, 6, 1], [6, 1, 5, 2], [6, 5, 2, 1]]
In another language, you may have to implement your own helper functions to iterate through permutations (possibly using recursion), and list flattening.

In Java you can do it like the following(first get a permutation of all the indexes and then use that to generate the ans):
public class RowWisePermutation {
public static void main(String[] args) {
int[][] A = {
{1},
{5, 2},
{6}
};
generateRowWisePermutation(A);
}
public static List<List<Integer>> generateRowWisePermutation(int[][] matrix) {
List<Integer> temp = new ArrayList<>();
List<List<Integer>> ans = new ArrayList<>();
List<List<Integer>> indexPermutation = new ArrayList<>();
int[] indexArr = new int[matrix.length];
for(int i = 0; i < matrix.length; i++) {
indexArr[i] = i;
}
backtrack(indexArr, temp, indexPermutation);
System.out.println(indexPermutation);
for(int i = 0; i < indexPermutation.size(); i++) {
List<Integer> row = new ArrayList<>();
List<Integer> indices = indexPermutation.get(i);
for(Integer index : indices) {
for(int j = 0; j < matrix[index].length; j++) {
row.add(matrix[index][j]);
}
}
ans.add(row);
}
System.out.println(ans);
return ans;
}
private static void backtrack(int[] arr, List<Integer> temp,
List<List<Integer>> indexPermutation) {
if(temp.size() == arr.length) {
indexPermutation.add(new ArrayList<>(temp));
return;
}
for(int i = 0; i < arr.length; i++) {
if(temp.contains(i)) { continue; }
temp.add(arr[i]);
backtrack(arr, temp, indexPermutation);
temp.remove(temp.size() - 1);
}
}
}

Related

Sort a List in Dart based on how another List was sorted

I am trying to sort a list with reference to another list. Consider this example,
List<String> a = ["a", "b", "c"];
List<int> b = [2, 3, 1];
Now, I want the result to be like this,
a = ["c", "a", "b"];
b = [1, 2, 3];
How can I achieve this result?
You can achieve this by create a Map that holds the mappings for the letters to your numbers, i.e. 2 has a assigned to it, 3 has b etc.
Now you can sort your list normally and after that recreate your other list based on the mappings that you stored before sorting:
main() {
List<String> letters = ["a", "b", "c"];
final List<int> numbers = [2, 3, 1];
final Map<int, String> mappings = {
for (int i = 0; i < numbers.length; i++)
numbers[i]: letters[i]
};
numbers.sort();
letters = [
for (int number in numbers) mappings[number]
];
print(letters); // [c, a, b]
print(numbers); // [1, 2, 3]
}
I used collection for for this example. This syntax for collection literals was introduced in Dart 2.3.
Learn more.
You can easily turn this about and map the numbers to your letters instead. That would look like this:
main() {
final List<String> letters = ["a", "b", "c"];
List<int> numbers = [2, 3, 1];
final Map<String, int> mapping = {
for (int i = 0; i < letters.length; i++)
letters[i]: numbers[i]
};
letters.sort((a, b) => b.compareTo(a));
numbers = [
for (String letter in letters) mapping[letter]
];
print(letters); // [c, b, a]
print(numbers); // [1, 3, 2]
}
Note that I sorted the letters in a descending order here by turning about the compareTo as well (by default a.compareTo(b) is used by List.sort).
If your Lists have duplicate elements, you won't be able to use a Map. I'd instead use package:tuple and then use the same approach of combining the two Lists into a single List<Tuple2>, sorting that, and extracting the values:
import 'package:tuple/tuple.dart';
void main() {
var a = ["a", "b", "c", "d"];
var b = [2, 3, 1, 1];
var combined = <Tuple2<int, String>>[
for (var i = 0; i < b.length; i += 1) Tuple2(b[i], a[i]),
];
combined.sort((tuple1, tuple2) => tuple1.item1.compareTo(tuple2.item1));
for (var i = 0; i < combined.length; i += 1) {
a[i] = combined[i].item2;
b[i] = combined[i].item1;
}
print(a); // Prints: [c, d, a, b]
print(b); // Prints: [1, 1, 2, 3]
}
I use this way to solve the problem:
List<String> strings = ["a", "b", "c", "c"];
List<int> numbers = [2, 3, 1, 0];
List<int> storeNumbers = List.from(numbers);
List<int> storeIndex = [];
//sorting numbers list
numbers.sort((a, b) => a.compareTo(b));
//get the index of numbers list elements before the sorting
for (int i = 0; i < numbers.length; i++) {
for (int j = 0; j < storeNumbers.length; j++) {
if (numbers[i] == storeNumbers[j]) {
storeIndex.add(j);
}
}
}
//generate a new string list based on the indexes we get
strings =
List.generate(strings.length, (index) => strings[storeIndex[index]]);
print(strings);//output:[c, c, a, b]
print(numbers);//output:[0, 1, 2, 3]

How do I account for duplicate values when solving the the two sum problem using a hash table?

Say I have the classic Two Sum Problem but with a twist
If I am given a list of integers and target
I need to print all the pairs of values that add up to the sum
Without repeating symmetrical values
Without reusing a value
I am trying to avoid the brute force approach for obvious reasons, but if I implement a hash-map with each value as the key and the element being the frequency of that value in the original array. How do I get the algorithm to only print each value pair once?
function findPairs(arr, target){
let hashMap = {};
let results = [];
for(let i = 0; i < arr.length; i++){
if(hashMap.hasOwnProperty(arr[i])){
hashMap[arr[i]]++;
}else{
hashMap[arr[i]] = 1;
}
}
for(let i = 0; i < arr.length; i++){
let diff = target - arr[i];
if(hashMap.hasOwnProperty(diff) && hashMap[diff] > 0){
results.push([arr[i], diff]);
hashMap[diff]--;
}
}
console.log(results);
}
findPairs([1, 3, -1, 11, 7], 10);
findPairs([5, 5, 5, 5, 5], 10);
findPairs([1, 3, -1, 11, 7], 10)
(3, 7)
(-1, 11)
findPairs([5, 5, 5], 10)
(5, 5)
findPairs([5, 5, 5, 5], 10)
(5, 5)
(5, 5)
findPairs([5, 5, 5, 5, 5], 10)
(5, 5)
(5, 5)
findPairs([5, 5, 5, 5, 5, 5 ], 10)
(5, 5)
(5, 5)
(5, 5)
This is the summary of the question as far as I understood:
Your array can have duplicate elements eg:- [1, 2, 3, 2, 4]
You want to print duplicate [4, 1, 2, 3, 2, 4] as (2, 4), (2, 4)
vector<pair<int, int> > findPairs(vector<int> arr, int target){
int size = arr.size();
map<int, int> hashMap;
for(int i = 0; i < size; i++){
// C++ map assigns 0 as default if the key is not present, C++ map uses Red Black Tree
if(hashMap[arr[i]] == 0)
hashMap[arr[i]] = 1;
else
hashMap[arr[i]]++;
}
/** Use to store result in (int, int) form
* Vector is a Dynamic array
*/
vector<pair<int, int> > results;
for(int i = 0; i < size; i++){
int diff = target - arr[i];
hashMap[arr[i]]--;
if(hashMap[diff] >= 1)
results.push_back(make_pair(arr[i], diff));
hashMap[diff]--;
}
return results;
}
This code is based on the examples you have provided in the question.

Sort an large array, keeping some elements in place (every language)

Can everybody help me? I have a problem: Given an array of array elements (Unlimited number of array elements). Sort the elements in ascending order, but keep any elements with the value -1 in the original position.
example: a=[4, -1, 5, 1, 8, 3, 2, -1]
after sort: a=[1, -1, 2, 3, 4, 5, 8, -1]
Here's how you might accomplish that in C#:
using System;
using System.Collections.Generic;
namespace NameSpace
{
class Class
{
static int[] a = { 4, -1, 5, 1, 8, 3, 2, -1 };
static List<int> Storage = new List<int>();
static int indexToAdd = 0;
static void Main()
{
foreach(int i in a)
{
if(i != -1)
{
Storage.Add(i);
}
}
Storage.Sort();
for(int i = 0; i < Storage.Count; i++)
{
if(a[indexToAdd + i] == -1)
{
indexToAdd++;
}
a[indexToAdd + i] = Storage[i];
}
foreach(int i in a)
{
Console.WriteLine(i);
}
Console.Read();
}
}
}
You can create a new list with the indices of every item that is not -1, i.e. the indices of the items that need sorting, then follow one of the examples in this RosettaCode Task: Sort disjoint sublist

Make 2D array into 1D array in Processing

I am trying to flatten a two dimensional array into a one dimensional array. This is what I currently have. I would like the flatten out my array so that the one dimensional array looks like this
int[] oneDim = {1, 2, 3, 4, 5, 6, 7, 8 ,9 ,10, 11, 12};
This is what I currently have. I dont really know how to go about doing this. All help and input is appreciated.
void setup() {
int[][] twoDim = { {1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12} };
int[] oneDim = new int[twoDim.length];
for (int i = 0; i < twoDim.length; i++) {
for (int j = 0; j < twoDim[i].length; j++) {
oneDim[j] += twoDim[j][i];
}
}
println(oneDim);
}
int[][] twoDim = { {1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12} };
int x = twoDim.length;
int y = twoDim[0].length;
int[] oneDim = new int[x*y];
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
oneDim[i*y + j] = twoDim[i][j];
}
}
println(oneDim);
Here's a hint: the usual formula for mapping two dimensions to one is: width*y + x, where width is the number of elements in each row (4, in your case, as given by twoDim[i].length, assuming they are all the same length), 'x' is the iterator over columns (j, in your case), and y is the iterator over rows (i for you).
You will want to check that the size of your one dimensional array is sufficient to accept all the elements of twoDim. It doesn't look big enough as it is - it needs to be twoDim[i].length * twoDim.length elements long, at least.
You're currently writing the same row of data over and over again, because you're assigning to oneDim[j] in the inner loop for every iteration of the outer loop. Try assigning to oneDim (once it is of appropriate size) using the formula I suggested at the start of this answer instead.

Check if two arrays are cyclic permutations

Given two arrays, how do you check if one is a cyclic permutation of the other?
For example, given a = [1, 2, 3, 1, 5], b = [3, 1, 5, 1, 2], and c = [2, 1, 3, 1, 5] we have that a and b are cyclic permutations but c is not a cyclic permutation of either.
Note: the arrays may have duplicate elements.
The standard trick here is to concatenate one of the arrays with itself, and then try to find the 2nd array in the concatenated array.
For example, 'a' concatenated with itself is:
[1, 2, 3, 1, 5, 1, 2, 3, 1, 5]
Since you do see 'b' in this array starting from the 3rd element then a and b are cyclic permutations.
If A and B are cyclic permutations of each other, A will be found in doubled list BB (as will B in AA).
The efficient way to handle large amounts of data, is to transform each of them into a 'canonical' form then compare to see of they're equal. For this problem you can choose as the canonical form of all the rotated permutations the one that 'sorts smallest'.
So the canonical form for 'a' and 'b' is [1, 2, 3, 1, 5] which are equal so they are acyclic permutations.
The canonical form for 'c' is [1, 3, 1, 5, 2] which is different.
Here is simple adhoc approach to findout cyclic permutations with O(n) time complexity.
a = [1, 2, 3, 1, 5], b = [3, 1, 5, 1, 2]
Find index of b[0] in a[], lets say index is 'x'.Then start
navigating in both the array's. a[] starts from index 'x' and b[]
starts from '0'. Such that both of them must have same values. If
not, they are not cyclic.
Here is the sample code.
public class CyclicPermutation {
static char[] arr = { 'A', 'B', 'C', 'D' };
static char[] brr = { 'C', 'D', 'K', 'B' };
boolean dec = false;
public static void main(String[] args) {
boolean avail = true;
int val = getFirstElementIndex(brr[0]);
if(val ==Integer.MIN_VALUE){
avail = false;
return;
}
for (int i = val, j = 0; j <= brr.length-1; ) {
if (i > arr.length-1) {
i = 0;
}
if (arr[i] == brr[j]) {
i++;
j++;
} else {
avail = false;
System.out.println(avail);
return;
}
}
System.out.println(avail);
}
public static int getFirstElementIndex(char c) {
for (int i = 0; i <= arr.length; i++) {
if (arr[i] == c) {
return i;
}
}
return Integer.MIN_VALUE;
}
}

Resources