Tuesday, July 21, 2015

[CC150v5] 8.4 Design a Parking Lot - Shuatiblog.com



lintcode 498. Parking Lot
在职刷题 + System Design + 面试准备的路上
How to design parking system: 需要以parking lot为视角进行操作, 然后主体主要有两个,vehicle和parking spot. 如果以最简单的logic来分析, parking lot里有list of spots. 每辆车会占用一个spot, 开出去会使得一个spot available. Vehichle也可能分为car, bus, truck等,spot也可能分多种。

像这种管理类问题,如果两个对象主体之间产生操作关系,最好的易于扩展的方式是添加一个新的主体,比如receipt或ticket来处理vehicle和spot的关系,并可以记录停车时间和价格等信息。同理,记录租书, 吃饭, 预定等都适用。parking system只需要去控制ticket就可以完成对vehicle和spot的调控
https://www.cnblogs.com/grandyang/p/5656870.html
Design a parking lot.
see CC150 OO Design for details.
1) n levels, each level has m rows of spots and each row has k spots.So each level has m x k spots.
2) The parking lot can park motorcycles, cars and buses
3) The parking lot has motorcycle spots, compact spots, and large spots
4) Each row, motorcycle spots id is in range[0,k/4)(0 is included, k/4 is not included), compact spots id is in range [k/4,k/4*3) and large spots id is in range [k/4*3,k).
5) A motorcycle can park in any spot
6) A car park in single compact spot or large spot
7) A bus can park in five large spots that are consecutive and within same row. it can not park in small spots
Example
level=1, num_rows=1, spots_per_row=11
parkVehicle("Motorcycle_1") // return true
parkVehicle("Car_1") // return true
parkVehicle("Car_2") // return true
parkVehicle("Car_3") // return true
parkVehicle("Car_4") // return true
parkVehicle("Car_5") // return true
parkVehicle("Bus_1") // return false
unParkVehicle("Car_5")
parkVehicle("Bus_1") // return true

CareerCup上的原题,请参见我之前的博客8.4 Parking Lot 停车场问题
LintCode的这道题的C++的OJ应该有问题,因为我的代码在本地调试都正确,不知道为何通过不了OJ,有没有大神持有同样的观点?

复制代码
// enum type for Vehicle
enum class VehicleSize {
    Motorcycle,
    Compact,
    Large
};

class Vehicle {
public:
    virtual VehicleSize size() {}
    virtual int spot_num() {}
};

class Bus: public Vehicle {
public:
    VehicleSize size() {
        return VehicleSize::Large;
    }
    int spot_num() {
        return 5;
    }
};

class Car: public Vehicle {
public:
    VehicleSize size() {
        return VehicleSize::Compact;
    }
    int spot_num() {
        return 1;
    }
};

class Motorcycle: public Vehicle {
public:
    VehicleSize size() {
        return VehicleSize::Motorcycle;
    }
    int spot_num() {
        return 1;
    }
};

class Level {
public:
    Level(int num_rows, int spots_per_row) {
        int moto = spots_per_row / 4;
        moto_spots.resize(moto);
        int car = spots_per_row / 4 * 3;
        compact_spots.resize(car - moto);
        large_spots.resize(spots_per_row - car);
    }
    
    bool park_vehicle(Vehicle* vehicle, VehicleSize size, int num) {
        if (size == VehicleSize::Motorcycle) {
            for (int i = 0; i < moto_spots.size(); ++i) {
                if (moto_spots[i] == NULL) {
                    moto_spots[i] = vehicle;
                    vehicle_to_spot[vehicle][VehicleSize::Motorcycle] = i;
                    return true;
                }
            }
            return false;
        } else if (size == VehicleSize::Compact) {
            for (int i = 0; i < compact_spots.size(); ++i) {
                if (compact_spots[i] == NULL) {
                    compact_spots[i] = vehicle;
                    vehicle_to_spot[vehicle][VehicleSize::Compact] = i;
                    return true;
                }
            }
            for (int i = 0; i < large_spots.size(); ++i) {
                if (large_spots[i] == NULL) {
                    large_spots[i] = vehicle;
                    vehicle_to_spot[vehicle][VehicleSize::Large] = i;
                    return true;
                }
            }
            return false;
        } else if (size == VehicleSize::Large) {
            for (int i = 0; i < large_spots.size(); ++i) {
                if (large_spots[i] == NULL) {
                    bool can_park = true;
                    for (int j = i; j < i + num; ++j) {
                        if (large_spots[j] != NULL) {
                            can_park = false;
                            break;
                        }
                    }
                    if (can_park) {
                        for (int j = i; j < i + num; ++j) {
                            large_spots[j] = vehicle;
                        }
                        vehicle_to_spot[vehicle][VehicleSize::Large] = i;
                        return true;
                    }
                }
            }
            return false;
        }
    }
    
    void unpark_vehicle(Vehicle *vehicle) {
        map<VehicleSize, int> spot = vehicle_to_spot[vehicle];
        VehicleSize size = vehicle->size();
        if (spot.count(size)) {
            int idx = spot[size];
            if (size == VehicleSize::Motorcycle) {
                moto_spots[idx] = NULL;
            } else if (size == VehicleSize::Compact) {
                compact_spots[idx] = NULL;
            } else {
                for (int i = idx; i < large_spots.size(); ++i) {
                    if (large_spots[i] == vehicle) {
                        large_spots[i] = NULL;
                    } else {
                        break;
                    }
                }
            }
        } else if (size == VehicleSize::Compact && spot.count(VehicleSize::Large)) {
            int idx = spot[VehicleSize::Large];
            large_spots[idx] = NULL;
        }
    }
    
private:
    vector<Vehicle*> moto_spots;
    vector<Vehicle*> compact_spots;
    vector<Vehicle*> large_spots;
    map<Vehicle*, map<VehicleSize, int>> vehicle_to_spot;
};

class ParkingLot {
public:
    // @param n number of leves
    // @param num_rows  each level has num_rows rows of spots
    // @param spots_per_row each row has spots_per_row spots
    ParkingLot(int n, int num_rows, int spots_per_row) {
        for (int i = 0; i < n; ++i) {
            Level *level = new Level(num_rows, spots_per_row);
            levels.push_back(level);
        }
    }

    // Park the vehicle in a spot (or multiple spots)
    // Return false if failed
    bool parkVehicle(Vehicle &vehicle) {
        for (int i = 0; i < levels.size(); ++i) {
            if (levels[i]->park_vehicle(&vehicle, vehicle.size(), vehicle.spot_num())) {
                vehicle_to_level[&vehicle] = levels[i];
                return true;
            }
        }
        return false;
    }

    // unPark the vehicle
    void unParkVehicle(Vehicle &vehicle) {
        Level *level = vehicle_to_level[&vehicle];
        if (level) {
            level->unpark_vehicle(&vehicle);
        }
    }
private:
    vector<Level*> levels;
    map<Vehicle*, Level*> vehicle_to_level;
};

[CC150v5] 8.4 Design a Parking Lot - Shuatiblog.com
  1. A parking lot has multiple Levels.
  2. A Level has multiple Parking Spot.
  3. A Spot can park motorcycle, car or bus, which all belongs to Vehicle.
Implement methods:
  1. Vehicle.parkInSpot(Spot s)
  2. Vehicle.leaveSpot(Spot s)
  3. Vehicle.canFitIn(Spot s)
  4. ParkingLot.parkVehicle(Vehicle v)
  5. Level.parkVehicle(Vehicle v)
  6. Level.parkVehicleAtSpot(Vehicle v, Spot s)
  7. Level.findAvailableSpot(VehicleType vt)
First understand the requirement, what kind of parking lot? ==> talk and define user cases.
Parking lot for public or club(so maybe user type: vip etc) or malls?

there may be multiple main comments, what we should focus?
Manage park slot and help user find a slot; or payment system?
What kind of parking lot:
Whether its charged and if so how?
The ticket includes info such as enter time and  parking slot?
How the slot is assigned? the customer find a slot himself or the admin at entrance assign one?

Whether there are different types of parking slot for different types of cars?
Single or multiple entrance?
then list main component and talk with the interviewer about them.

ParkingSystem - the facade, root class.
ParkingSlot
Floor(Level)
Ticket

Draw UML class digram.
Abstraction, subclasses etc.
Consider design pattern?
Singleton, composite? etc...
https://xmruibi.gitbooks.io/interview-preparation-notes/content/OOD/DesignExamples/ParkingLot.html
  • Vehicle
    • size of vehicle (small, medium, large)
    • status of vehicle (run or parked)
  • Sedan, SUV, Bus, Truck... extends Vehicle
  • Slot
    • size of slot
    • status (available or not)
  • Lot
    • hold slots in lot

Diagram

Classes Diagram



  • Vehicle
public class Vehicle {
    private final int size;
    private final int lisense;
    private boolean status;
    private Lot lot;

    public Vehicle(int size) {
        this.size = size;
        lisense = this.hashCode();
        lot = Lot.getInstance();
    }

    public void setStatus(boolean status) {
        this.status = status;
    }

    private Slot findSlot() {

        Slot slot;
        switch (this.size) {
        case 1:
            slot = lot.getSmallSlots().remove(0);
        case 2:
            slot = lot.getCompactSlots().remove(0);
        case 3:
            slot = lot.getLargeSlots().remove(0);
        default:
            slot = null;
        }
        return slot;
    }

    public void park() {
        Slot slot = findSlot();
        if (slot != null) {
            lot.occupiedSlots.put(this.lisense, slot);
            slot.occupy(this);
        }
    }

    public void leave() {
        Slot slot = lot.occupiedSlots.remove(this.lisense);
        slot.release();
        switch (this.size) {
        case 1:
            lot.getSmallSlots().add(slot);
        case 2:
            lot.getCompactSlots().add(slot);
        case 3:
            lot.getLargeSlots().add(slot);
        }
    }
}

public class Car extends Vehicle{
    public Car(){
        super(1);        
    }
}
public class Truck extends Vehicle{
    public Truck(){
        super(2);        
    }
}
// ... other type of vehicle
  • Lot
public class Lot {
    private static Lot lot = null;

    private static final int NUMBER_OF_SMALL_SLOTS = 10;
    private static final int NUMBER_OF_COMPACT_SLOTS = 10;
    private static final int NUMBER_OF_LARGE_SLOTS = 10;

    public Map<Integer, Slot> occupiedSlots;
    private List<Slot> smallSlots;
    private List<Slot> compactSlots;
    private List<Slot> largeSlots;

    private Lot() {
        smallSlots = new LinkedList<>();
        compactSlots = new LinkedList<>();
        largeSlots = new LinkedList<>();
        occupiedSlots = new HashMap<>();
        for (int i = 1; i <= NUMBER_OF_SMALL_SLOTS; i++)
            smallSlots.add(new Slot(i, 1));

        for (int i = 1; i <= NUMBER_OF_COMPACT_SLOTS; i++)
            compactSlots.add(new Slot(i, 2));

        for (int i = 1; i <= NUMBER_OF_LARGE_SLOTS; i++)
            largeSlots.add(new Slot(i, 3));

    }

    public List<Slot> getSmallSlots() {
        return smallSlots;
    }

    public List<Slot> getCompactSlots() {
        return compactSlots;
    }

    public List<Slot> getLargeSlots() {
        return largeSlots;
    }

    public static Lot getInstance() {
        if (lot == null)
            lot = new Lot();
        return lot;
    }
}
  • Slot

public class Slot {
    private final int id;
    private final int size;
    private boolean available;
    private Vehicle vehicle;

    public Slot(int id, int size) {
        this.id = id;
        this.size = size;
        this.available = true;
    }

    public void occupy(Vehicle v) {
        this.vehicle = v;
        this.available = false;
    }

    public void release() {
        this.vehicle = null;
        this.available = true;
    }
}
http://www.coderanch.com/t/628047/patterns/Parking-Lot-Design
http://javajuggler.blogspot.com/2011/01/oo-design-for-parkinglot.html
ParkingLot: this class can park or unpark and holds finite number of spaces and the spaces are held by two lists one for Parkedspaces and one for unparkedSpaces
ParkingSpace: is another class that represents the actual parking space. It needs a property to specify whether it is a compact/handicap/regular parking space
Car: is the final class that has a property of what kind of car it is and if it is parked, the slot number where it is parked.
The Car object can be further subclassed as CompactCar, HandiCapCar, RegularCar instead of the booleans. Same with the ParkingSpace as well.
public class ParkingLot {
    int totalSpaces = 100;
    public static List ParkingSpace parkedSpaces = new ArrayList();
    public static List ParkingSpace emptySpaces = new ArrayList();

    public static void park(Car car) {
        //Traverse though the emptySpaces list to find the 
        //spot for specific car type
        //set the car object for that parkingspace
        //change it to park. move the object into parkedSpaces
        // remove it from emptySpaces
    }

    public static void unPark(int parkingSpot) {
        //get the parkingspot from array
        //set the parkingspace to available
    }

    public static boolean isEmpty() {
        if (emptySpaces.size() > 0)
            return true;
        return false;
    }

    public static void main(String args[]) {
        //build emptySpaces list. Insert 100 parking spaces 
        //with their type properties
        Car car = new Car();
        car.setCompact(true);
        if(ParkingLot.isEmpty())
            ParkingLot.park(car);

        ParkingLot.unPark(20);
    }
}

public class ParkingSpace {

    boolean isCompact;
    boolean isRegular;
    boolean isHandicap;

    //setter and getter calls

}

public class Car {
   boolean isCompact;
   boolean isRegular;
   boolean isHandicap;
   int parkingSlotNumber;

   public Car() {
   }

   public void setParkingSlotNumber(int value) {
    this.parkingSlotNumber = value;
   }
}

public class ParkingLot {
    private Level[] levels;
    private final int NUM_LEVELS = 5;

    public ParkingLot() {
        levels = new Level[NUM_LEVELS];
        for (int i = 0; i < NUM_LEVELS; i++) {
            levels[i] = new Level(i, 30);
        }
    }

    /* Park the vehicle in a spot (or multiple spots). Return false if failed. */
    public boolean parkVehicle(Vehicle vehicle) {
        for (int i = 0; i < levels.length; i++) {
            if (levels[i].parkVehicle(vehicle)) {
                return true;
            }
        }
        return false;
    }
}

/* Represents a level in a parking garage */
public class Level {
    private int floor;
    private ParkingSpot[] spots;
    private int availableSpots = 0; // number of free spots
    private static final int SPOTS_PER_ROW = 10;

    public Level(int flr, int numberSpots) {
        floor = flr;
        spots = new ParkingSpot[numberSpots];
        int largeSpots = numberSpots / 4;
        int bikeSpots = numberSpots / 4;
        int compactSpots = numberSpots - largeSpots - bikeSpots;
        for (int i = 0; i < numberSpots; i++) {
            VehicleSize sz = VehicleSize.Motorcycle;
            if (i < largeSpots) {
                sz = VehicleSize.Large;
            } else if (i < largeSpots + compactSpots) {
                sz = VehicleSize.Compact;
            }
            int row = i / SPOTS_PER_ROW;
            spots[i] = new ParkingSpot(this, row, i, sz);
        }
        availableSpots = numberSpots;
    }

    public int availableSpots() {
        return availableSpots;
    }

    /* Try to find a place to park this vehicle. Return false if failed. */
    public boolean parkVehicle(Vehicle vehicle) {
        if (availableSpots() < vehicle.getSpotsNeeded()) {
            return false;
        }
        int spotNumber = findAvailableSpots(vehicle);
        if (spotNumber < 0) {
            return false;
        }
        return parkStartingAtSpot(spotNumber, vehicle);
    }

    /* Park a vehicle starting at the spot spotNumber, and continuing until vehicle.spotsNeeded. */
    private boolean parkStartingAtSpot(int spotNumber, Vehicle vehicle) {
        vehicle.clearSpots();
        boolean success = true;
        for (int i = spotNumber; i < spotNumber + vehicle.spotsNeeded; i++) {
             success &= spots[i].park(vehicle);
        }
        availableSpots -= vehicle.spotsNeeded;
        return success;
    }

    /* find a spot to park this vehicle. Return index of spot, or -1 on failure. */
    private int findAvailableSpots(Vehicle vehicle) {
        int spotsNeeded = vehicle.getSpotsNeeded();
        int lastRow = -1;
        int spotsFound = 0;
        for (int i = 0; i < spots.length; i++) {
            ParkingSpot spot = spots[i];
            if (lastRow != spot.getRow()) {
                spotsFound = 0;
                lastRow = spot.getRow();
            }
            if (spot.canFitVehicle(vehicle)) {
                spotsFound++;
            } else {
                spotsFound = 0;
            }
            if (spotsFound == spotsNeeded) {
                return i - (spotsNeeded - 1);
            }
        }
        return -1;
    }

    public void print() {
        int lastRow = -1;
        for (int i = 0; i < spots.length; i++) {
            ParkingSpot spot = spots[i];
            if (spot.getRow() != lastRow) {
                System.out.print("  ");
                lastRow = spot.getRow();
            }
            spot.print();
        }
    }

    /* When a car was removed from the spot, increment availableSpots */
    public void spotFreed() {
        availableSpots++;
    }
}
https://hellosmallworld123.wordpress.com/2014/08/03/design-a-parking-lot/
Why use PriorityQueue?
public class Lot {
    PriorityQueue<ParkingSpace> handicapParkingSpaceQueue;
    PriorityQueue<ParkingSpace> normalParkingSpaceQueue;
    HashMap<Integer, ParkingSpace> occupiedSpace = new HashMap<Integer, ParkingSpace>();
     
    public Lot(int noHandicapParking, int totalNoParking) {
        int num = 0;
        handicapParkingSpaceQueue = new PriorityQueue<ParkingSpace>(noHandicapParking, new ParkingComparator());
        normalParkingSpaceQueue = new PriorityQueue<ParkingSpace>(totalNoParking - noHandicapParking, new ParkingComparator());
        for (int i = 0; i < noHandicapParking; i++) {
            handicapParkingSpaceQueue.add(new HandicapParkingSpace(num++));
        }
        for (int i = noHandicapParking; i < totalNoParking; i++) {
            normalParkingSpaceQueue.add(new ParkingSpace(num++));
        }
    }
     
     
    //take the first available space and park
    public boolean park(Car c) {
        if (c.isHandicap()) { //get the first handicap space if possible
            if (!handicapParkingSpaceQueue.isEmpty()) {
                ParkingSpace takenSpace = handicapParkingSpaceQueue.remove();
                occupiedSpace.put(c.getNum(), takenSpace);
                takenSpace.take();
                return true;
            }
        }
        if (!normalParkingSpaceQueue.isEmpty()) {
            ParkingSpace takenSpace = normalParkingSpaceQueue.remove();
            occupiedSpace.put(c.getNum(), takenSpace);
            takenSpace.take();
            return true;
        }
        return false;
    }
     
    //valte parking get the car for the customer
    public long unpark(Car c) {
        if (!occupiedSpace.containsKey(c.getNum())) {
            return -1; //no such car in this lot
        }
        ParkingSpace freeSpace = occupiedSpace.remove(c.getNum());
        if (freeSpace.type == ParkingSpace.TYPE.HANDICAP) {
            handicapParkingSpaceQueue.add(freeSpace);
        }
        else {
            normalParkingSpaceQueue.add(freeSpace);
        }
        return freeSpace.leave();
    }
     
    public boolean isNormalFull(){
        return normalParkingSpaceQueue.isEmpty();
    }
     
    public boolean isHandicapFull() {
        return handicapParkingSpaceQueue.isEmpty();
    }
     
    //comparator to sort the parking space in num
    class ParkingComparator implements Comparator<ParkingSpace> {
        @Override
        public int compare(ParkingSpace arg0, ParkingSpace arg1) {
            if (arg0.num < arg1.num)
                return -1;
            else if (arg0.num > arg1.num){
                return 1;
            }
            return 0;
        }
         
    }
http://www.jianshu.com/p/2bd60b69393d
  1. n levels, each level has m rows of spots and each row has k spots.So each level has m x k spots.
  2. The parking lot can park motorcycles, cars and buses
  3. The parking lot has motorcycle spots, compact spots, and large spots
  4. Each row, motorcycle spots id is in range [0,k/4)(0 is included, k/4 is not included), compact spots id is in range [k/4,k3/4) and large spots id is in range [k3/4,k].
  5. A motorcycle can park in any spot
  6. A car park in single compact spot or large spot
  7. A bus can park in five large spots that are consecutive and within same row. it can not park in small spots
Example
level=1, num_rows=1, spots_per_row=11
parkVehicle("Motorcycle_1") // return true
parkVehicle("Car_1") // return true
parkVehicle("Car_2") // return true
parkVehicle("Car_3") // return true
parkVehicle("Car_4") // return true
parkVehicle("Car_5") // return true
parkVehicle("Bus_1") // return false
unParkVehicle("Car_5")
parkVehicle("Bus_1") // return true
// enum type for Vehicle
enum class VehicleSize {
    Motorcycle,
    Compact,
    Large,
    Default
};

class Vehicle {
public:
    virtual VehicleSize size() {
        return VehicleSize::Default;
    }
};

class Bus: public Vehicle {
public:
    VehicleSize size() {
        return VehicleSize::Large;
    }
};

class Car: public Vehicle {
public:
    VehicleSize size() {
        return VehicleSize::Compact;
    }
};

class Motorcycle: public Vehicle {
public:
    VehicleSize size() {
        return VehicleSize::Motorcycle;
    }
};

class Level {
private:
    vector<Vehicle* > motoSpots;
    vector<Vehicle* > compactSpots;
    vector<Vehicle* > largeSpots;
    map<Vehicle*, map<VehicleSize, int>> vehicle2spot;
public:
    Level(int num_rows, int spots_per_row) {
        int motoSpotSize = spots_per_row / 4;
        motoSpots.resize(motoSpotSize);
        int compactSpotSize = spots_per_row * 3 / 4 - motoSpotSize;
        compactSpots.resize(compactSpotSize);
        int largeSpotSize = spots_per_row - spots_per_row * 3 / 4 + 1;
        largeSpots.resize(largeSpotSize);
    }

    int canParkVehicle(Vehicle* vehicle, VehicleSize size, int num) {
        if (size == VehicleSize::Motorcycle) {
            for(int i = 0; i < motoSpots.size(); i++) {
                if (motoSpots[i] == NULL) {
                    return i;
                }
            }
            return -1;
        } else if (size == VehicleSize::Compact) {
            for(int i = 0; i < compactSpots.size(); i++) {
                if (compactSpots[i] == NULL) {
                    return i;
                }
            }
            return -1;
        } else {
            for(int i = 0; i < largeSpots.size(); i++) {
                if (largeSpots[i] == NULL) {
                    bool flag = true;
                    for(int j = i; j < i + num; j++) {
                        if (largeSpots[i] != NULL) {
                            flag = false;
                            break;
                        }
                    }
                    if (flag) {
                        return i;
                    }
                }
            }
            return -1;
        }
    }

    void parkVehicle(Vehicle* vehicle, VehicleSize parkSpotType, int index, int num) {
        if (parkSpotType == VehicleSize::Motorcycle) {
            motoSpots[index] = vehicle;
        } else if (parkSpotType == VehicleSize::Compact) {
            compactSpots[index] = vehicle;
        } else {
            for(int i = index; i < index + num; i++) {
                largeSpots[i] = vehicle;
            }
        }
        vehicle2spot[vehicle][parkSpotType] = index;
    }

    void unParkVehicle(Vehicle *vehicle) {
        map<VehicleSize, int> spot = vehicle2spot[vehicle];
        VehicleSize size = vehicle->size();
        int index = spot[size];
        if (size == VehicleSize::Motorcycle) {
            motoSpots[index] = NULL;
        } else if (size == VehicleSize::Compact) {
            compactSpots[index] = NULL;
        } else {
            for(int i = index; i < largeSpots.size(); i++) {
                if (largeSpots[i] == vehicle) {
                    largeSpots[i] = NULL;
                } else {
                    break;
                }
            }
        }
    }
};

class ParkingLot {
private:
    vector<Level* > levels;
    map<Vehicle*, Level*> vehicle2level;
public:
    // @param n number of leves
    // @param num_rows  each level has num_rows rows of spots
    // @param spots_per_row each row has spots_per_row spots
    ParkingLot(int n, int num_rows, int spots_per_row) {
        for(int i = 0; i < n; i++) {
            Level *level = new Level(num_rows, spots_per_row);
            levels.push_back(level);
        }
    }

    // Park the vehicle in a spot (or multiple spots)
    // Return false if failed
    bool parkVehicle(Vehicle &vehicle) {
        VehicleSize size = vehicle.size();
        if (size == VehicleSize::Motorcycle) {
            cout << "Moto" << endl;
            if (!parkInMotoSpot(vehicle)) {
                if (!parkInCompactSpot(vehicle)) {
                    return parkInLargeSpot(vehicle, 1);
                }
            }
            return true;
        } else if (size == VehicleSize::Compact) {
            cout << "Compact" << endl;
            if (!parkInCompactSpot(vehicle)) {
                return parkInLargeSpot(vehicle, 1);
            }
        } else if (size == VehicleSize::Large) {
            cout << "Bus" << endl;
            return parkInLargeSpot(vehicle, 5);
        } else {
            return false;
        }
    }

    bool parkInMotoSpot(Vehicle &vehicle) {
        for(int i = 0; i < levels.size(); i++) {
            int index = levels[i]->canParkVehicle(&vehicle, VehicleSize::Motorcycle, 1);
            if (index != -1) {
                levels[i]->parkVehicle(&vehicle, VehicleSize::Motorcycle, index, 1);
                vehicle2level[&vehicle] = levels[i];
                return true;
            }
        }
        return false;
    }

    bool parkInCompactSpot(Vehicle &vehicle) {
        for(int i = 0; i < levels.size(); i++) {
            int index = levels[i]->canParkVehicle(&vehicle, VehicleSize::Compact, 1);
            cout << index << endl;
            if (index != -1) {
                levels[i]->parkVehicle(&vehicle, VehicleSize::Compact, index, 1);
                vehicle2level[&vehicle] = levels[i];
                return true;
            }
        }
        return false;
    }

    bool parkInLargeSpot(Vehicle &vehicle, int num) {
        for(int i = 0; i < levels.size(); i++) {
            int index = levels[i]->canParkVehicle(&vehicle, VehicleSize::Large, num);
            if (index != -1) {
                levels[i]->parkVehicle(&vehicle, VehicleSize::Large, index, num);
                vehicle2level[&vehicle] = levels[i];
                return true;
            }
        }
        return false;
    }

    // unPark the vehicle
    void unParkVehicle(Vehicle &vehicle) {
        Level *level = vehicle2level[&vehicle];
        if (level) {
            level->unParkVehicle(&vehicle);
        }
    }
};
https://www.nowtoshare.com/zh/Article/Index/70566
isParkable should be at ParkingLot class.


http://stackoverflow.com/questions/764933/amazon-interview-question-design-an-oo-parking-lot
https://blogs.oracle.com/parijat/entry/a_parking_lot_problem
https://www.isr.umd.edu/~austin/ense623.d/projects06.d/ParkingLotProject.pdf
Read full article from [CC150v5] 8.4 Design a Parking Lot - Shuatiblog.com

Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts