시스템 설계 면접 질문 너무 개방적이어서 올바른 준비 방법을 알기가 너무 어렵습니다. 이제 구매 후 Amazon, Microsoft 및 Adobe의 디자인 라운드를 해독할 수 있습니다. 이 책은. 매일 수정 하나 디자인 질문 그리고 나는 당신이 디자인 라운드를 깨뜨릴 수 있다고 약속합니다.
차례
설명
“기사가 목표물에 도달하기위한 최소 단계”문제는 N x N 차원의 정사각형 체스 판, 기사 조각의 좌표 및 목표 셀이 주어 졌다는 것입니다. 나이트 조각이 표적 셀에 도달하기 위해 취한 최소 단계 수를 알아보십시오.
기사 단계: 체스 규칙에 따라 기사는 한 방향으로 2 칸, 수직 방향으로 1 칸을 이동합니다 (또는 그 반대).
예
(kx,ky) = (1,1) & (tx,ty) = (15,15)
Minimum number of moves = 10
(kx,ky) = (2,8) & (tx,ty) = (8,4)
Minimum number of moves = 4
(kx,ky) = (2,8) & (tx,ty) = (8,4)
Minimum number of moves = 4
솔루션 유형
-
폭 우선 검색
-
동적 프로그래밍
폭 우선 검색
접근
아이디어는 수행하는 것입니다 BFS 기사의 초기 위치에서 시작합니다. 주어진 위치 (또는 좌표)에서 반복적으로 모든 다음 셀 (및 다음 셀)로 진행하고, 다음 셀 각각을 방문합니다. 기사 단계 방법. 순회는 BFS 대기열을 사용하여 수행됩니다. 각 대기열 노드 특정 셀에 도달하기 위해 취한 단계 수와 함께 BFS 순회 중에 만난 셀의 좌표를 저장합니다. 대상 셀이 BFS 큐에서 팝되면 단계 수 값이 필수 응답입니다.
암호알고리즘
1. Define a class that has following data variables: 1. x: to store x-coordinate of the cell. 2. y: to store y-coordinate of the cell. 3. steps: number of steps required to reach that cell starting from co-ordinates of the Knight. 2. Create a BFS queue that stores class objects as nodes. 3. Begin the Iterative BFS traversal. 4. In every step of the iterative traversal, pop a node from the queue. say,the node is front. 5. If the cell at coordinates (front.y, front.x) is the target cell, return the value of front.steps. 1. Else, continue the iterative traversal.
암호
기사가 목표에 도달하기위한 최소 단계를 찾는 C ++ 프로그램
#include <iostream> #include <bits/stdc++.h> using namespace std; // definition of queue node class Node { public: // y-coordinate int y; // x-coordinate int x; // number of steps to reach (y,x) int steps; // constructor Node(int i,int j,int moves) { y = i; x = j; steps = moves; } }; // traversal array along rows int dx[] = {-2, -1, 1, 2, -2, -1, 1, 2}; // traversal array along columns int dy[] = {-1, -2, -2, -1, 1, 2, 2, 1}; // BFS to return number of steps required to reach from source to target int BFS(Node source, Node target, int N) { // set to mark a cell as visited unordered_set <string> visited; // BFS queue queue <Node> q; // push the source node q.push(source); // BFS traversal while(!q.empty()) { Node front = q.front(); q.pop(); // if target coordinate is reached if(front.y == target.y && front.x == target.x) return front.steps; // traverse all neighbors of current cell for(int i=0;i<8;i++) { int next_y = front.y + dy[i]; int next_x = front.x + dx[i]; // store coordinates of a cell as string string search = to_string(next_y) + '|' + to_string(next_x); // move to neighbor cell if it is not visited lies within the N x N chessboard if(visited.find(search) == visited.end() && next_y > 0 && next_x > 0 && next_y <= N && next_x <= N) { Node next(next_y,next_x,front.steps+1); q.push(next); visited.insert(search); } } } } int main() { // dimensions of the square chessboard int N = 8; // coordinates of source & target cell Node source(2,8,0), target(8,4,-1); cout<<"Number of steps : "<<BFS(source,target,N)<<endl; return 0; }
Number of steps : 4
기사가 목표에 도달하기위한 최소 단계를 찾는 Java 프로그램
import java.util.*; import java.io.*; class TutorialCup { // definition of queue node static class Node { // y-coordinate int y; // x-coordinate int x; // number of steps to reach (y,x) int steps; // constructor Node(int i,int j,int moves) { y = i; x = j; steps = moves; } }; // traversal array along rows static int dx[] = {-2, -1, 1, 2, -2, -1, 1, 2}; // traversal array along columns static int dy[] = {-1, -2, -2, -1, 1, 2, 2, 1}; // BFS to return number of steps required to reach from source to target static int BFS(Node source, Node target, int N) { // set to mark a cell as visited HashSet <String> visited = new HashSet<>(); // BFS queue Queue <Node> q = new LinkedList<>(); // push the source node q.add(source); // BFS traversal while(!q.isEmpty()) { Node front = q.poll(); // if target coordinate is reached if(front.y == target.y && front.x == target.x) return front.steps; // traverse all neighbors of current cell for(int i=0;i<8;i++) { int next_y = front.y + dy[i]; int next_x = front.x + dx[i]; // store coordinates of a cell as string String search = next_y + "|" + next_x; // move to neighbor cell if it is not visited lies within the N x N chessboard if(visited.contains(search) == false && next_y > 0 && next_x > 0 && next_y <= N && next_x <= N) { Node next = new Node(next_y,next_x,front.steps+1); q.add(next); visited.add(search); } } } return 0; } public static void main (String[] args) { // dimensions of the square chessboard int N = 8; // coordinates of source & target cell Node source = new Node(2,8,0); Node target = new Node(8,4,-1); System.out.println("Number of steps : "+BFS(source,target,N)); } }
Number of steps : 4
복잡성 분석
- 시간 복잡성 : T (n) = O (N ^ 2)
정사각형 행렬이 있고 최악의 경우이기 때문입니다. 따라서 우리는 각 세포를 다루어야 할 수도 있습니다. 이것이 XNUMX 차 시간 복잡성이 달성되는 방법입니다. - 공간 복잡성 : A (n) = O (N ^ 2)
여기서 우리는 알고리즘이 다항식 공간 복잡성을 가지고 있기 때문에 BFS를 사용했습니다.
동적 프로그래밍
접근
문제 접근 방식을 이해하려면 아래 사항을 고려하십시오.
아래의 가정을 고려하십시오.
- 체스 판은 표준 N x N 사각형입니다.
- kx & ky는 기사의 좌표입니다.
- tx & ty는 대상 셀의 좌표입니다.
비선형 위치 : 기사 및 대상 셀이 다른 행과 열을 따라있는 경우. 즉 kx not = tx 및 ky not = 타이.
- 예 : (kx, ky) = (3,3) & (tx, ty) = (6,6)
- 목표를 향해 2 단계 만 이동합니다.
- (3,3)-> (4,5) 및 (3,3)-> (5,4)
- 따라서 동적 프로그래밍, minSteps {(3,3) ~ (6,6)} = 1 + [minSteps {(4,5) ~ (6,6)} or minSteps {(5,4) ~ (6,6)}]
선형 위치 : 기사 및 대상 셀이 동일한 행 또는 열을 따라있는 경우. 즉 kx = tx or ky = ty.
- 예 : (kx, ky) = (2,4) & (tx, ty) = (7,4)
- 목표를 향한 총 4 단계 이동은 다음과 같습니다.
- (2,4)-> (4,5) 및 (2,4)-> (4,3),이 두 단계는 동일합니다.
- (2,4)-> (3,6) 및 (2,4)-> (3,2),이 두 단계는 동일합니다.
- 따라서 동적 프로그래밍, minSteps {(2,4) ~ (7,4)} = 1 + 분[minSteps {(2,4) ~ (4,5)} , minSteps {(2,4) ~ (3,6)}].
코너 케이스 : 기사 나 표적 중 하나가 모퉁이에 있고 [ABS(kx-tx) , 복근(ky-ty)] = [1,1]. 그러면 목표에 도달하는 최소 단계는 4입니다.
다음 코드 스 니펫은 기본 사례를 나타냅니다.
기본 케이스 : 기본 사례는 아래에서 설명합니다.
다음 코드 스 니펫은 기본 사례를 나타냅니다.
또한 동적 프로그래밍 표를 사용한 방정식은:
- 테이블 [abs (kx – tx)] [abs (ky – ty)] = 기사의 위치 (kx, ky)에서 목표 위치 (tx, ty)까지 도달하는 최소 단계 수.
- 테이블 [abs (kx – tx)] [abs (ky – ty)] = 테이블 [abs (ky – ty)] [abs (kx – tx)].
암호알고리즘
1. Define the solution for corner cases. i.e. when the knight or target are at 4 corners of the board and difference in their positions are (1,1). The minimum number of moves from source to target is 4. These positions are depicted below: 2. Define the base cases as discussed below: 1. when the Knight & target are at adjacent squares (along the same row/column), minimum number of moves required to reach the destination is 3. 2. when the Knight & target are at adjacent squares but lie diagonally to each other, minimum number of moves required to reach the destinations is 2. 3. when Knight & target are at positions as depicted in the image, minimum number of moves required to reach destination is 1. 4. If the Knight & target are at same position, minimum number of moves required is 0. 3. For any other case, refer Linear Positions & Non-Linear Positions in the approach section.
암호
기사가 목표에 도달하기위한 최소 단계를 찾는 C ++ 프로그램
#include <iostream> #include <bits/stdc++.h> using namespace std; int minStepsRecur(int kx, int ky, int tx, int ty, vector<vector<int>>& table) { // when Knight & Target are at same position if (kx == tx && ky == ty) return table[0][0]; else { // if value in the table has been calculated already if (table[abs(kx - tx)][abs(ky - ty)] != 0) return table[abs(kx - tx)][abs(ky - ty)]; // Linear Positions /* Knight can move to -->2 different squares<-- that goes towards the Target */ // Non-Linear Positions /* Knight can move to 4 different squares that goes towards the Target of which -->2 are equivalent<-- */ // For every position of Knight & Target // there are 2 different positions i.e. (x1,y1) & (x2,y2), the Knight can move to. else { int x1, y1, x2, y2; // the values of (x1,y1) & (x2,y2) depend upon relative positions of Knight & Target // (x1,y1) & (x2,y2) are midway between (kx,ky) & (tx,ty) // Their calculations are made accordingly if (kx <= tx) { if (ky <= ty) { x1 = kx + 2; y1 = ky + 1; x2 = kx + 1; y2 = ky + 2; } else { x1 = kx + 2; y1 = ky - 1; x2 = kx + 1; y2 = ky - 2; } } else { if (ky <= ty) { x1 = kx - 2; y1 = ky + 1; x2 = kx - 1; y2 = ky + 2; } else { x1 = kx - 2; y1 = ky - 1; x2 = kx - 1; y2 = ky - 2; } } // The minimum steps from (kx,ky) to (tx,ty) = 1 + minimum of steps from (x1, y1) to (x2, y2). table[abs(kx - tx)][abs(ky - ty)] = 1 + min(minStepsRecur(x1, y1, tx, ty, table),minStepsRecur(x2, y2, tx, ty, table)); // exchanging the coordinates x with y of both knight and target will result in same min moves. table[abs(ky - ty)][abs(kx - tx)] = table[abs(kx - tx)][abs(ky - ty)]; return table[abs(kx - tx)][abs(ky - ty)]; } } } int minSteps(int kx, int ky, int tx, int ty, int n) { // Corner Cases if ((kx == 1 && ky == 1 && tx == 2 && ty == 2) || (kx == 2 && ky == 2 && tx == 1 && ty == 1)) return 4; else if ((kx == 1 && ky == n && tx == 2 && ty == n - 1) || (kx == 2 && ky == n - 1 && tx == 1 && ty == n)) return 4; else if ((kx == n && ky == 1 && tx == n - 1 && ty == 2) || (kx == n - 1 && ky == 2 && tx == n && ty == 1)) return 4; else if ((kx == n && ky == n && tx == n - 1 && ty == n - 1) || (kx == n - 1 && ky == n - 1 && tx == n && ty == n)) return 4; else { vector <int> row(20,0); vector <vector<int>> table; for(int i=0; i<20; i++) table.push_back(row); // Base Cases table[2][1] = 1; table[1][2] = 1; table[1][1] = 2; table[2][0] = 2; table[0][2] = 2; table[1][0] = 3; table[0][1] = 3; // Linear & Non-Linear positions return minStepsRecur(kx, ky, tx, ty, table); } } int main() { int n = 8; int kx = 2, ky = 8, tx = 8, ty = 4; cout<<"Number of steps : "<<minSteps(kx,ky,tx,ty,n)<<endl; return 0; }
Number of steps : 4
기사가 목표에 도달하기위한 최소 단계를 찾는 Java 프로그램
import java.util.*; import java.io.*; class TutorialCup { static int minStepsRecur(int kx, int ky, int tx, int ty, int [][] table) { // when Knight & Target are at same position if (kx == tx && ky == ty) return table[0][0]; else { // if value in the table has been calculated already if (table[Math.abs(kx - tx)][Math.abs(ky - ty)] != 0) return table[Math.abs(kx - tx)][Math.abs(ky - ty)]; // Linear Positions /* Knight can move to -->2 different squares<-- that goes towards the Target */ // Non-Linear Positions /* Knight can move to 4 different squares that goes towards the Target of which -->2 are equivalent<-- */ // For every position of Knight & Target // there are 2 different positions i.e. (x1,y1) & (x2,y2), the Knight can move to. else { int x1, y1, x2, y2; // the values of (x1,y1) & (x2,y2) depend upon relative positions of Knight & Target // (x1,y1) & (x2,y2) are midway between (kx,ky) & (tx,ty) // Their calculations are made accordingly if (kx <= tx) { if (ky <= ty) { x1 = kx + 2; y1 = ky + 1; x2 = kx + 1; y2 = ky + 2; } else { x1 = kx + 2; y1 = ky - 1; x2 = kx + 1; y2 = ky - 2; } } else { if (ky <= ty) { x1 = kx - 2; y1 = ky + 1; x2 = kx - 1; y2 = ky + 2; } else { x1 = kx - 2; y1 = ky - 1; x2 = kx - 1; y2 = ky - 2; } } // The minimum steps from (kx,ky) to (tx,ty) = 1 + minimum of steps from (x1, y1) to (x2, y2). table[Math.abs(kx - tx)][Math.abs(ky - ty)] = 1 + Math.min(minStepsRecur(x1, y1, tx, ty, table),minStepsRecur(x2, y2, tx, ty, table)); // exchanging the coordinates x with y of both knight and target will result in same min moves. table[Math.abs(ky - ty)][Math.abs(kx - tx)] = table[Math.abs(kx - tx)][Math.abs(ky - ty)]; return table[Math.abs(kx - tx)][Math.abs(ky - ty)]; } } } static int minSteps(int kx, int ky, int tx, int ty, int n) { // Corner Cases if ((kx == 1 && ky == 1 && tx == 2 && ty == 2) || (kx == 2 && ky == 2 && tx == 1 && ty == 1)) return 4; else if ((kx == 1 && ky == n && tx == 2 && ty == n - 1) || (kx == 2 && ky == n - 1 && tx == 1 && ty == n)) return 4; else if ((kx == n && ky == 1 && tx == n - 1 && ty == 2) || (kx == n - 1 && ky == 2 && tx == n && ty == 1)) return 4; else if ((kx == n && ky == n && tx == n - 1 && ty == n - 1) || (kx == n - 1 && ky == n - 1 && tx == n && ty == n)) return 4; else { int [][] table = new int[20][20]; // Base Cases table[2][1] = 1; table[1][2] = 1; table[1][1] = 2; table[2][0] = 2; table[0][2] = 2; table[1][0] = 3; table[0][1] = 3; // Linear & Non-Linear positions return minStepsRecur(kx, ky, tx, ty, table); } } public static void main (String[] args) { int n = 8; int kx = 2, ky = 8, tx = 8, ty = 4; System.out.println("Number of steps : "+minSteps(kx,ky,tx,ty,n)); } }
Number of steps : 4
복잡성 분석
- 시간 복잡성: T (n) = O [abs ( (kx-tx) * (ky-ty) )]
시작 및 대상 셀에 의해 형성된 부분 행렬에 들어오는 셀만 다루기 때문입니다. 따라서이 솔루션은 위의 솔루션과 유사한 XNUMX 차 시간 복잡도를 갖지만. - 공간 복잡성: A (n) = O [abs ( (kx-tx) * (ky-ty) )]
어디에,
- (kx, ky) = 기사의 위치
- (tx, ty) = 타겟 셀의 위치
