0

I am working on Leetcode #332. It is a graph problem.

Someone already copied the question here: Is there any chance to get rid of that error?(Memory Limit Exceeded)

Here is the problem page on Leetcode: https://leetcode.com/problems/reconstruct-itinerary/

I've been trying to debug my solution for the past 2 hours. Please set me on the right track. I am using a DFS approach similar to that in the published solution. I know the bug is related to the part of my code that modifies the graph matrix and itinerary array at the end of the for loop's contents.

I'm including a couple hardcoded test cases below.

/**
 * @param {string[][]} tickets
 * @return {string[]}
 */
var findItinerary = function(tickets) {
    var airports = listAirports(tickets);
    console.log('airports: ' + airports);
    
    var graph = populateGraph(airports, tickets);
    console.log('graph: ' + graph);
    
    // get index of departure airport.
    var da = airports.indexOf("JFK");
    console.log('JFK index: ' + da);
    
    var completeItinerary = ["JFK"];
        
    var DFS = function(itinerary, da) {
        console.log('DFS(' + itinerary + ',' + da + ')');
        // console.log('itinerary: ' + itinerary);
        for (var aa=0; aa<airports.length; aa++) { // aa is arrival airport
            console.log('aa: ' + aa);
            console.log('graph: ' + graph);
            console.log('checking for flights to '+airports[aa]);
            // console.log('graph[' +da+ '][' +aa+ ']: ' + graph[da][aa]);
            if (graph[da][aa] > 0) { // there are nonzero tix for this route.
                console.log('flight to '+airports[aa] + ' exists.')
                graph[da][aa]--;
                itinerary.push(airports[aa]);
                console.log('new itinerary: ' + itinerary);
                console.log('itin l: ' + itinerary.length);
                // console.log('tix length + 1: ' + (tickets.length + 1));
                if (itinerary.length === (tickets.length + 1)) {
                    console.log('length reached with ' +itinerary);
                    if (completeItinerary.length === 1) {
                        completeItinerary = itinerary;
                        console.log('completeItinerary: ' + completeItinerary);
                    } else {
                        completeItinerary = lexMin(completeItinerary, itinerary);
                    }
                } else if (itinerary.length < (tickets.length+1)){
                    // console.log('itin length != tix.l+1');
                    DFS(itinerary, aa);
                }
                console.log('itinerary before slicing: ' + itinerary);
                itinerary = itinerary.slice(0,itinerary.length - 1);
                console.log('itinerary after slicing: ' + itinerary);
                graph[da][aa]++;
            }
        }
    }
    DFS(["JFK"], da);
    return completeItinerary;
};

var listAirports = function(tickets) {
    var airports = [];
    for (var i = 0; i < tickets.length; i++) {
        var ticket = tickets[i];
        if (airports.indexOf(ticket[0]) === -1) {
            airports.push(ticket[0]);
        }
        if (airports.indexOf(ticket[1]) === -1) {
            airports.push(ticket[1]);
        }
    }
    return airports;
}

var populateGraph = function(airports, tickets) {    
    // initialize graph
    var graph = [];
    for (var r = 0; r < airports.length; r++) {
        graph[r] = [];
        for (var c = 0; c < airports.length; c++) {
            graph[r][c] = 0;
        }
    }
    
    // insert tickets into graph
    // columns are departures
    // rows are arrivals
    for (var i = 0; i < tickets.length; i++) {
        var departure = airports.indexOf(tickets[i][0]);
        var arrival = airports.indexOf(tickets[i][1]);
        graph[departure][arrival]++;
    }
    return graph;
}

// return the lexicographically smallest list
var lexMin = function(list1, list2) {
    console.log('lexMin('+list1+','+list1+')');
    if (list1.length !== list2.length) {
        console.log('TODO: handle different sized lists');
        // should never happen in this problem.
    } else {
        for (var i = 0; i < list1.length; i++) {
            if (list1[i] < list2[i]) {
                return list1;
            } else if (list2[i] > list1[i]) {
                return list2;
            }
        }
        // if lists are identical, just return either.
        return list1;
    }
}

Here is a test input that my code successfully solved.

[["MUC","LHR"],["JFK","MUC"],["SFO","SJC"],["LHR","SFO"]]

Solution: ["JFK","MUC","LHR","SFO","SJC"]

And here is a test input that my code failed on.

[["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]]

My incorrect solution: ["JFK","SFO","ATL","JFK","ATL","SFO"]

The correct solution: ["JFK","ATL","JFK","SFO","ATL","SFO"]

GNG
  • 1,341
  • 2
  • 23
  • 50
  • 1
    Wow! that's mouthful , Its hard to say for anyone that "what's wrong with your code" because more code more bugs... I did review the problem on Leetcode, Its very easy, first find a starting point, they didn't tell about it, so you need to find starting position, so you could use state to represent if you already visited a node or not, using Depth-First-Search is nice idea! [here is an example of this algorithms](https://stackoverflow.com/questions/68037804/get-possible-question-answer-paths-javascript)... – Nur Oct 17 '21 at 01:19
  • I didn't post any answer, cse I want you to solve this by yourself ... If you stuck, feel free to ask! – Nur Oct 17 '21 at 01:23
  • 1
    Please [edit] your question, add programming-language tag and add hard coded test data and the expected output. – c0der Oct 17 '21 at 03:59
  • Is this the same https://stackoverflow.com/questions/62903795/javascript-function-to-show-routes-of-the-cities-followed? – Bergi Oct 17 '21 at 16:29
  • 1
    I haven't dug through this wall of code, but you should notice in the leetcode description, that yours was an alternate acceptable route but that if there was more than one, you needed the alphabetically earlier one, and `ATL` comes before `SFO`. So if you're not already doing this, you probably need to find all possible solutions and then find the alphabetically minimal one, or organize your search so that the alphabetically earlier one will always show up first. – Scott Sauyet Oct 18 '21 at 13:29

0 Answers0