Leetcode Weekly – 173 – 3

Time:2020-9-26

1334. The city with the least neighbors in the threshold distance

Hi, everyone. I’m a pig. Welcome to the weekly leetcode quiz of the “baby can understand” series.

This is the third question in issue 173 and 1334 in the list of questions – “the city with the least neighbors within the threshold distance”

Title Description

YesnCities, press from0reachn-1Number. Here’s an array of sidesedgesIn whichedges[i] = [fromi, toi, weighti]RepresentativefromiAndtoiTwo way weighted edge between two cities, the distance threshold is an integerdistanceThreshold

Return can reach other cities through some paths with the least number and path distancemaximumFordistanceThresholdThe city of. If there are more than one such city, the city with the largest number is returned.

Attention, connect the cityiandjThe distance of the path is equal to the sum of the weights of all edges along the path.

Example 1:

Leetcode Weekly - 173 - 3

Input: n = 4, edges = [[0,1,3], [1,2,1], [1,3,4], [2,3,1]], distancethreshold = 4
Output: 3
Explanation: the urban distribution map is shown above.
The neighboring cities within the threshold distance of each city distancethreshold = 4 are:
City 0 - > [City 1, city 2]
City 1 - > [City 0, city 2, city 3]
City 2 - > [City 0, city 1, city 3]
City 3 - > [City 1, city 2]
Cities 0 and 3 have 2 neighbors within the threshold distance of 4, but we have to return to city 3 because it has the largest number.

Example 2:

Leetcode Weekly - 173 - 3

Input: n = 5, edges = [[0,1,2], [0,4,8], [1,2,3], [1,4,2], [2,3,1], [3,4,1]], distancethreshold = 2
Output: 0
Explanation: the urban distribution map is shown above.
The neighboring cities within the threshold distance of each city distancethreshold = 2 are:
City 0 - > [City 1]
City 1 - > [City 0, city 4]
City 2 - > [city 3, city 4]
City 3 - > [City 2, city 4]
City 4 - > [City 1, city 2, city 3]
City 0 has only 1 neighbor city within the threshold distance of 4.

Tips:

  • 2 <= n <= 100
  • 1 <= edges.length <= n * (n - 1) / 2
  • edges[i].length == 3
  • 0 <= fromi < toi < n
  • 1 <= weighti, distanceThreshold <= 10^4
  • All(fromi, toi)It’s all different.

Official difficulty

MEDIUM

Solutions

After reading the topic, the first reaction is the routine. Hum, look at the piggy set to take you away!

The content of the title is very straightforward, so I won’t explain it too much. If we look at the data provided by the title abstractly, imagine the city as a point, the road between the cities as the line between the points, and the length of the road is the weight of the line, then the data provided by the title is actually a graph with undirected power.

Undirected means that the connection has no direction. For example, if the direct distance from a to B is 3, then the direct distance from B to a is 3. Power means that the connection between our different points may be different. For example, if the direct distance from a to B is 3, then the direct distance from B to C may be 5. This is that they have different weights.

Why should we explain the problem of undirected power first? Because there are many ways to deal with graphs. Whether there is direction and weight will affect the logic of data processing.

But if you continue to say that, it is not the style of a pig! Piggy first said this concept, is to let the unknown friends not be frightened by those strange terms. Hum! It’s all paper brain strokes! Pig style, of course, or to start with a chestnut.

Leetcode Weekly - 173 - 3

Corresponding to the above figure, suppose we get the data as follows:

5
[
  [1, 4, 10],
  [0, 2, 6],
  [3, 4, 1],
  [1, 2, 2],
  [1, 0, 1],
  [3, 2, 3],
]
4

So the first problem we face is how to store these data. After all, it is unrealistic to traverse the search every time. Here, we can expect that the data to be accessed frequently is the length of each line segment, so the corresponding data access will be o (1) time consuming. Speaking of this, I believe that my friends have already thought of it, that is to map directly with the index. Since the names of the points in our data are all consecutive numbers starting from 0, we can naturally identify them based on the array subscript. So the first problem is solved. We can get code like this:

//JS multidimensional array ah, said that many are tears
const distance = Array.from({ length: n }, () => new Uint16Array(n));
for (const edge of edges) {
  distance[edge[0]][edge[1]] = distance[edge[1]][edge[0]] = edge[2];
}

Then we come to the core problem, that is, how to know the shortest distance from each point to other points. Let’s take a look at the situation in the chestnuts above from city 0 to city 2

  • The direct distance from 0 to 2 is 6.
  • The direct distance from 0 to 1 is 1:

    • The direct distance from 1 to 2 is 4.
    • The direct distance from 1 to 4 is 1:1

      • The direct distance between 4 and 3 is 1:1

        • The direct distance between 3 and 2 is 1.

We have listed all the cases that do not include the way back. We can see that there are three routes from 0 to 2

  • The total distance is 6.
  • The total distance is 5.
  • The total distance is 4.

Here are some simple information:

  1. We don’t have to think about turning back, because we need to know the shortest distance, and the length of our road is positive.
  2. The direct distance between two points is not necessarily the shortest.
  3. It looks like a long path, the real direct distance is not necessarily long.

Speaking of this, I believe the partners have found that we can not directly get this result through some calculation methods. Only by traversing each case based on data can we know the final result.

Depth first traversal?

Since traversal is mentioned, and it is the sum of the distances from the starting point to the end point, then some partners may wonder whether we can use the depth first traversal mentioned before? We can give it a try.

Suppose we now need to find the shortest distance from 0 to 3. So we started to traverse. Suppose the current traversal is to visit point 2 first. Then the situation can be as follows:

Leetcode Weekly - 173 - 3

We will get two routes successively, which are 0 > 2 > 3, with length of 7; 0 > 2 > 1 > 4 > 3, with length of 12.

In depth first traversal, in order to prevent infinite loops from accessing points, we use a set to record the visited points. In the above traversal process, if we use purple to identify the points that have been accessed, the result is that all the points have been accessed.

Next, the traversal continues. Here comes the line 0 to 1. However, since it has been visited, it will not go on. However, in fact, we know that the shortest path from 0 to 3 is this line: 0 > 1 > 4 > 3, and the length is 3.

This is an easy mistake to make in the first place to solve this problem. The same is true for breadth first traversal. But in fact, we can not use depth first traversal to achieve, but the logic will be more complex. And because the efficiency is not high, we may try to solve it in a different way.

Floyd Warshall algorithm

Let’s ignore the scary looking name and return to the chestnuts.

In the previous analysis, we have listed all cases from 0 to 2. Although there are three paths, they can be summed up in two ways: from 0 directly to 2, or from 0 to 2 with the help of other points. As for the path with the help of multiple points, it can be understood that the path from 0 to 3 is from 3 to 2, and 0 to 3 is not directly connected, so it can be from 0 to 4 to 3. and so on.

We can replace the above analysis with more abstract points, such as the shortest distance from I to J. Suppose the shortest distance isd[i][j]Then it may come from the direct distance between the two pointsgraph[i][j]Or a connection with the help of the k-pointd[i][k] + d[k][j]。 As for the ones hered[i][k]andd[k][j]In the same way, we can get it.

When we calculate the shortest distance from each point to other points based on the above idea. The rest is very simple, according to the given threshold of the topic to count and judge can get the results. The specific process is as follows:

  1. Initialize the storage of the graph according to the data provided. Because we need to calculate the shortest distance, we can fill the nonexistent line as a very large number, so as to facilitate the subsequent calculation. Because the weight range is[1, 10^4]So I filled it10001
  2. Try to list all the possibilities, from point a to point C with the help of point B, then judge according to the only two results, and update the shortest distance from point a to point C.
  3. According to the threshold given by the topic, traverse the count and get the result.

Based on the above process, the following code can be obtained:

const findTheCity = (n, edges, distanceThreshold) => {
  const distance = Array.from({ length: n }, () => new Uint16Array(n).fill(10001));
  for (const edge of edges) {
    distance[edge[0]][edge[1]] = distance[edge[1]][edge[0]] = edge[2];
  }
  for (let i = 0; i < n; ++i) {
    for (let j = 0; j < n; ++j) {
      for (let k = 0; k < n; ++k) {
        if (k === j) continue;
        distance[j][k] = Math.min(distance[j][k], distance[j][i] + distance[i][k]);
      }
    }
  }

  let city = 0;
  let minNum = n;
  for (let i = 0; i < n; ++i) {
    let curNum = 0;
    for (let j = 0; j < n; ++j) {
      distance[i][j] <= distanceThreshold && ++curNum;
    }
    if (curNum <= minNum) { minNum = curNum; city = i; }
  }
  return city;
};

optimization

In the code above, there are three layersforThe structure of the loop can be understood as a very template implementation of Floyd Warshall algorithm. As long as you need to solve the problem based on this algorithm, you can set such a template. However, according to the specific situation, we can also do a little optimization. The following code mainly makes two small changes:

  1. Because this is an undirected graph, so ourdistanceThe matrix is actually symmetric along the diagonal. Naturally, we only need to do half of the calculation.
  2. We can end unnecessary cycles and calculations in advance according to some conditions, such as the shortest distance from a to B, where a is the intermediate point, or C is the intermediate point, but there is no path between a and C, so it is unnecessary to carry out subsequent processing.
const findTheCity = (n, edges, distanceThreshold) => {
  const MAX = 10001;
  const distance = Array.from({ length: n }, () => new Uint16Array(n).fill(MAX));
  for (const edge of edges) {
    distance[edge[0]][edge[1]] = distance[edge[1]][edge[0]] = edge[2];
  }
  for (let i = 0; i < n; ++i) {
    for (let j = 0; j < n; ++j) {
      if (i === j || distance[j][i] === MAX) continue;
      for (let k = j + 1; k < n; ++k) {
        distance[k][j] = distance[j][k] = Math.min(distance[j][k], distance[j][i] + distance[i][k]);
      }
    }
  }

  let city = 0;
  let minNum = n;
  for (let i = 0; i < n; ++i) {
    let curNum = 0;
    for (let j = 0; j < n; ++j) {
      distance[i][j] <= distanceThreshold && ++curNum;
    }
    if (curNum <= minNum) { minNum = curNum; city = i; }
  }
  return city;
};

This code has run 64ms, temporarily beats 100%

summary

In fact, piggy has been hesitant to add some seemingly frightening terms. So this article, piggy, dragged on for a long time. (I’m not looking for an excuse for procrastination, huh

In the end, piggy decided to explain his thoughts with straightforward chestnuts and words, but he would mention the strange looking nouns. The main reason is that I hope that my friends who don’t know much about it will not be scared by these nouns in the future. After all, they are all paper brain strokes, and friends and pigs are the best! Yeah, after this year, it’s really the most Pang

Back to this topic, there are many ways to deal with graphs. In fact, there are many other ways to deal with this problem, such as BellmanFord, Dijkstra and so on. If you are interested, you can urge the piglet to write a special topic about the picture. Momota~

Finally, as for the above optimization code, there is actually room for optimization. But little pig benzene, have little partner can help piggy? >.

Come on, Wuhan, God bless China

Related links

  • Weekly contest 173 topic list
  • Repo
  • My segment fault column
  • My Zhihu column

Leetcode Weekly - 173 - 3

Recommended Today

Explain idea git branch backoff specified historical version

scene When I submitted this modification to the local and remote branches, I found that there were still some changes missing in this submission, or this modification was totally wrong, but I also pushed it to the remote repository. How to go back? problem How can the content that has been submitted to the repository […]