private void find(String start, String end, Set<String> dict, HashSet<String> visited, ArrayList<String> current, List<List<String>> result, HashMap<String, ArrayList<String>> adj) {



        if (result.size() != 0 && current.size() > result.get(0).size()) {
            return;
        }

        if (start.equals(end)) {

            current.add(end);
            if (result.size() == 0 || current.size() == result.get(0).size()) {
                result.add(new ArrayList<String>(current));
            } else if (current.size() < result.get(0).size()) {
                result.clear();
                result.add(new ArrayList<String>(current));
            }
            current.remove(current.size() - 1);
            return;
        }

        ArrayList<String> available = null;

        if (adj.get(start) != null) {
            available = adj.get(start);
        } else {
            available = new ArrayList<String>();
            for (int i = 0; i < start.length(); i++) {
                char[] startChars = start.toCharArray();
                for (char j = 'a'; j <= 'z'; j++) {
                    startChars[i] = j;
                    String newStart = String.valueOf(startChars);
                    if (!visited.contains(newStart) && dict.contains(newStart)) {
                        available.add(newStart);
                    }
                }
            }
            adj.put(start, available);
        }
        for (String s : available) {
            if (!visited.contains(s)) {
                current.add(s);
                visited.add(s);
                find(s, end, dict, visited, current, result, adj);
                current.remove(current.size() - 1);
                //visited.remove(s);
            }

        }
        visited.removeAll(available);
    }