简体   繁体   中英

Permutations program using backtracking not working in Ruby

I am fairly new to Ruby programming and I am trying to write a Ruby code which will take a list of numbers in certain order and will return all the possible permutation in a list of permutation lists. I wrote this program successfully in Java a while ago and it worked and when I was trying to implement same logic in Ruby I am just getting list of empty lists instead of permutations. By initial debugging, I could observe that each permutation is being successfully built in temp_list list by backtrack method but somehow res is not retaining the pushed permutations properly. I think there is something wrong with my coding style in Ruby. Can someone please point out what the issue might be. I am attaching both my Ruby and Java codes.

My Ruby code goes here:

# @param [Object] nums : List of numbers Example: [1, 2, 3]
# @return [Object] res : List of all permutation lists Example [[1, 2, 3], [1, 3, 2]....]
def permute(nums)
  res = []
  temp_list = []
  backtrack(res, temp_list, nums)
  res
end

# @param [Object] res : List of all permutation lists Example [[1, 2, 3], [1, 3, 2]....]
# @param [Object] temp_list : List of permutation which is being built
# @param [Object] nums : Original nums list given to the permute method
def backtrack(res, temp_list, nums)
  if temp_list.size == nums.size
    res << temp_list
  else
    nums.each do |n|
      next if temp_list.include? n
      temp_list << n
      backtrack(res, temp_list, nums)
      temp_list.pop
    end
  end
end

My JAVA Code goes here:

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Srikiran Sistla on 4/3/2017.
 */
public class Q46 {
    public List<List<Integer>> permute(int[] num) {
        List<List<Integer>> res = new ArrayList<>();
        List<Integer> tempList = new ArrayList<>();
        backtrack(res, tempList, num);
        return res;
    }

    private void backtrack(List<List<Integer>> res, List<Integer> tempList, int[] num) {
        if (tempList.size() == num.length) res.add(new ArrayList<>(tempList));
        else {
            for (int n : num){
                if (tempList.contains(n)) continue;
                tempList.add(n);
                backtrack(res, tempList, num);
                tempList.remove(tempList.size()-1);
            }
        }
    }
}

It's wierd, but I had untangled your code:)

What you need is just make clone of your temp_list, before appending it to res: res << temp_list.dup

JFYI, you could save some time by just calling standard Array#permutation: [1,2,3].permutation.to_a # => [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM