Reputation: 159
A route is described as [1,2,3,4]. For the route [1,2,3,4] a duplicate solution would be [4,3,2,1]. I am able to print all permutations of the array, but how would I extract the "unique" routes.
permute(java.util.Arrays.asList(1,2,3,4), 0);
static void permute(java.util.List<Integer> arr, int k){
for(int i = k; i < arr.size(); i++){
java.util.Collections.swap(arr, i, k);
permute(arr, k+1);
java.util.Collections.swap(arr, k, i);
}
if (k == arr.size() -1){
System.out.println(java.util.Arrays.toString(arr.toArray()));
}
}
Upvotes: 1
Views: 398
Reputation: 88707
Well I'd say such a "path" could be described as a list of "hops" i.e. a tuple of adjacent points. Thus 1,2,3,4
could become [1,2],[2,3],[3,4]
. Now if you build the tuples using the smaller value first 4,3,2,1
would become [3,4],[2,3],[2,1]
- as you can see that would be the same tuples as for 1,2,3,4
. Thus a permutation would be equal to another if it has the same tuples in any order (i.e. a set of tuples).
Using that you could build a Map<Set<Tuple>, List<ArrayList<Integer>>>
to get all paths that have the same "hops". Just note that map keys should be immutable so it would be best to either use a true immutable set implementation or at least decorate it with Collections.unmodifiableSet()
.
Here's a possible Tuple
class you could use:
class Tuple {
private int l,r;
public Tuple( int a, int b ) {
if ( a > b ) {
l = b;
r = a;
} else {
l = a;
r = b;
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + l;
result = prime * result + r;
return result;
}
@Override
public boolean equals( Object obj ) {
if( this == obj ) return true;
if( obj == null ) return false;
if( getClass() != obj.getClass() ) return false;
Tuple other = (Tuple) obj;
if( l != other.l ) return false;
if( r != other.r ) return false;
return true;
}
@Override
public String toString() {
return "[" + l + ", " + r + "]";
}
}
Then pass the Map<Set<Tuple>, List<List<Integer>>>
to permute(...)
and fill it:
static void permute(List<Integer> arr, int k, Map<Set<Tuple>, List<List<Integer>>> results){
for(int i = k; i < arr.size(); i++){
Collections.swap(arr, i, k);
permute(arr, k+1, results);
Collections.swap(arr, k, i);
}
if (k == arr.size() -1){
Set<Tuple> path = new HashSet<>();
for( int i = 0; i < arr.size() - 1; i++ ) {
path.add( new Tuple(arr.get( i ), arr.get( i + 1 )) );
}
results.computeIfAbsent( Collections.unmodifiableSet( path ), v -> new ArrayList<List<Integer>>() ).add( new ArrayList<>( arr ) );
}
}
Using the map you could then get all the permutations that share the same "hops". In your case where there's basically one straight path from start to end or back there will be only 2 equal permutations.
Upvotes: 0
Reputation: 53
If you mean [1,2,3,4]=[4,3,2,1]=[1,3,2,4]=...,
1) transform each permutation in ArrayList
2) Sort each permutation by their natural sort order
3) Add all permutations sorted in a Set
Upvotes: 1