Binary Reflected Gray Code generation recursively
Not Gray Code

The first big issue with this code that I see is naming things. Naming a list list adds absolutely no semantic information. You're duplicating what the "syntax" already tells you. n also doesn't tell us anything. Let's try the following:

public static List&lt;String&gt; generateGray(List&lt;String&gt; currentGrayWords, int targetBitLength) {

public static List&lt;String&gt; generateGrayV2(List&lt;String&gt; currentGrayWords, int wordsToGenerate) {


Note that the semantics of these two methods are not interchangeable. There's quite a few assumptions you make about how parameters are passed in. The first assumption is that you think that the "currentGrayWords" are a valid and complete BRGC (and non-empty). The second assumption is that n is a clean power of two in the first version and positive in both versions.

Check your assumptions. Consider the following invocations that look completely harmless but generate totally unintended results:

generateGray(Collections.emptyList(), 8); // returns empty list
generateGray(Arrays.asList("0", "01", "10", "1"), 4); // returns inconsistent gray code
generateGray(Arrays.asList("0", "1"), 5); // stackoverflow because recursion never terminates
generateGrayV2(Arrays.asList("000", "001", "011", "010", "110", "111", "101", "100"), -4);
// stackoverflow, because it never terminates


Gray Code

As it stands your code isn't even correct. Wikipedia tells me that a binary reflected gray code works by concatenating the original list with each element having 0 prepended and the reflected original list with each element having 1 prepended. That reflection is conspiciously absent in the code you present here.

As such the following is what your code creates:

genGray(Collections.singletonList(""), 8);
"0" "1"
"00" "01" "10" "11" // gray-code property violated
"000" "001" "010" "011" "100" "101" "110" "111"


The correct sequence would've been:

"0" "1"
"00" "01" "11" "10"
"000" "001" "011" "010" "110" "111" "101" "100"


Method

What this code is missing is a comprehensive test-suite that actually checks inputs that you didn't consider when first writing this code. You may want to not expose the List&lt;String&gt; as input parameter. It could (should?) be something internal to what the code does.

Try to break your code! If you don't succeed, try harder. Throw things at it that "nobody would ever think of doing". That way when somebody actually does, the code handles it gracefully.

With recursion it's especially important to think of the "termination condition" in your code. Make sure whatever is thrown into the method, it always terminates. Stack Overflows are not an acceptable result ...