treemap/treeset 相关 1438,1779,3243,3244
Given an array of integers nums and an integer limit, return the size of the longest non-empty subarray such that the absolute difference between any two elements of this subarray is less than or equal to limit.
Example 1:
Input: nums = [8,2,4,7], limit = 4 Output: 2 Explanation: All subarrays are: [8] with maximum absolute diff |8-8| = 0 <= 4. [8,2] with maximum absolute diff |8-2| = 6 > 4. [8,2,4] with maximum absolute diff |8-2| = 6 > 4. [8,2,4,7] with maximum absolute diff |8-2| = 6 > 4. [2] with maximum absolute diff |2-2| = 0 <= 4. [2,4] with maximum absolute diff |2-4| = 2 <= 4. [2,4,7] with maximum absolute diff |2-7| = 5 > 4. [4] with maximum absolute diff |4-4| = 0 <= 4. [4,7] with maximum absolute diff |4-7| = 3 <= 4. [7] with maximum absolute diff |7-7| = 0 <= 4. Therefore, the size of the longest subarray is 2.
Example 2:
Input: nums = [10,1,2,4,7,2], limit = 5 Output: 4 Explanation: The subarray [2,4,7,2] is the longest since the maximum absolute diff is |2-7| = 5 <= 5.
Example 3:
Input: nums = [4,2,2,2,4,4,2,2], limit = 0 Output: 3
Constraints:
1 <= nums.length <= 1051 <= nums[i] <= 1090 <= limit <= 109
class Solution { public int longestSubarray(int[] nums, int limit) { TreeSet<Integer> tree = new TreeSet<Integer>((x,y)->{ return nums[x]==nums[y] ? x-y : nums[x]-nums[y]; }); int left = 0; int result = 0; for(int i=0; i < nums.length; i++){ tree.add(i); while(nums[tree.last()]-nums[tree.first()]>limit){ tree.remove(left++); } result = Math.max(result, i-left+1); } return result; } }
You are given two integers, x and y, which represent your current location on a Cartesian grid: (x, y). You are also given an array points where each points[i] = [ai, bi] represents that a point exists at (ai, bi). A point is valid if it shares the same x-coordinate or the same y-coordinate as your location.
Return the index (0-indexed) of the valid point with the smallest Manhattan distance from your current location. If there are multiple, return the valid point with the smallest index. If there are no valid points, return -1.
The Manhattan distance between two points (x1, y1) and (x2, y2) is abs(x1 - x2) + abs(y1 - y2).
Example 1:
Input: x = 3, y = 4, points = [[1,2],[3,1],[2,4],[2,3],[4,4]] Output: 2 Explanation: Of all the points, only [3,1], [2,4] and [4,4] are valid. Of the valid points, [2,4] and [4,4] have the smallest Manhattan distance from your current location, with a distance of 1. [2,4] has the smallest index, so return 2.
Example 2:
Input: x = 3, y = 4, points = [[3,4]] Output: 0 Explanation: The answer is allowed to be on the same location as your current location.
Example 3:
Input: x = 3, y = 4, points = [[2,3]] Output: -1 Explanation: There are no valid points.
Constraints:
1 <= points.length <= 104points[i].length == 21 <= x, y, ai, bi <= 104
附加要求: 会做频繁query, query的时候 时间复杂度应该为 log(n)
import java.util.*; class Solution3{ static Map<Integer, TreeSet<City>> xMap = new HashMap<>(); static Map<Integer, TreeSet<City>> yMap = new HashMap<>(); public static void main(String[] args) { String result = getClosest(new String[]{"a", "b", "c", "d"}, new int[]{1,1,3,4}, new int[]{1,2,3,4}, 1, 1); System.out.println(result); } public static String getClosest(String[] cities, int[] xs, int[] ys, int x, int y) { for(int i = 0; i < cities.length; i++) { //x轴归类 TreeSet<City> cList = xMap.getOrDefault(xs[i], new TreeSet<>((a, b)-> a.x - b.x)); cList.add(new City(ys[i], cities[i])); xMap.put(xs[i], cList); //y轴归类 cList = yMap.getOrDefault(ys[i], new TreeSet<>((a, b)-> a.x - b.x)); cList.add(new City(xs[i], cities[i])); yMap.put(ys[i], cList); } //find it return search(x, y); } private static String search(int x, int y) { //x轴最近 City xcity = searchX(y, xMap.get(x)); //y轴最近 City ycity = searchX(x, yMap.get(y)); if(xcity == null && ycity == null) return ""; if(xcity == null) return ycity.name; if(ycity == null) return xcity.name; return Math.abs(xcity.x - y) <= Math.abs(ycity.x - x) ? xcity.name : ycity.name; } private static City searchX(int y, TreeSet<City> set) { if(set.size() == 1) return null; City l = set.lower(new City(y, "")); City r = set.higher(new City(y, "")); if(l == null) return r; if(r == null) return l; if(y - l.x <= r.x - y) return l; return r; } }
n and a 2D integer array queries.There are n cities numbered from 0 to n - 1. Initially, there is a unidirectional road from city i to city i + 1 for all 0 <= i < n - 1.
queries[i] = [ui, vi] represents the addition of a new unidirectional road from city ui to city vi. After each query, you need to find the length of the shortest path from city 0 to city n - 1.
Return an array answer where for each i in the range [0, queries.length - 1], answer[i] is the length of the shortest path from city 0 to city n - 1 after processing the first i + 1 queries.
Example 1:
Input: n = 5, queries = [[2,4],[0,2],[0,4]]
Output: [3,2,1]
Explanation:

After the addition of the road from 2 to 4, the length of the shortest path from 0 to 4 is 3.

After the addition of the road from 0 to 2, the length of the shortest path from 0 to 4 is 2.

After the addition of the road from 0 to 4, the length of the shortest path from 0 to 4 is 1.
Example 2:
Input: n = 4, queries = [[0,3],[0,2]]
Output: [1,1]
Explanation:

After the addition of the road from 0 to 3, the length of the shortest path from 0 to 3 is 1.

After the addition of the road from 0 to 2, the length of the shortest path remains 1.
Constraints:
3 <= n <= 5001 <= queries.length <= 500queries[i].length == 20 <= queries[i][0] < queries[i][1] < n1 < queries[i][1] - queries[i][0]- There are no repeated roads among the queries.
class Solution { // 定义graph List<Integer>[] graph; public int[] shortestDistanceAfterQueries(int n, int[][] queries) { graph = new List[n]; // 建图 int[] result = new int[queries.length]; for(int i = 0; i < n - 1; i++) { graph[i] = new ArrayList(); graph[i].add(i + 1); } // query逐条添加到graph for(int i = 0; i < queries.length; i++) { int start = queries[i][0], end = queries[i][1]; graph[start].add(end); // bfs得到最短路径 result[i] = get(); } return result; } //bfs 计算最短路径 private int get() { Queue<Integer> queue = new LinkedList<>(); boolean[] visited = new boolean[graph.length]; queue.offer(0); int step = 0; while(!queue.isEmpty()) { int size = queue.size(); for(int i = 0; i < size; i++) { int curr = queue.poll(); if(curr == graph.length - 1) return step; for(int j : graph[curr]) { if(visited[j]) continue; visited[j] = true; queue.offer(j); } } step++; } return step; } }
You are given an integer n and a 2D integer array queries.
There are n cities numbered from 0 to n - 1. Initially, there is a unidirectional road from city i to city i + 1 for all 0 <= i < n - 1.
queries[i] = [ui, vi] represents the addition of a new unidirectional road from city ui to city vi. After each query, you need to find the length of the shortest path from city 0 to city n - 1.
There are no two queries such that queries[i][0] < queries[j][0] < queries[i][1] < queries[j][1].
Return an array answer where for each i in the range [0, queries.length - 1], answer[i] is the length of the shortest path from city 0 to city n - 1 after processing the first i + 1 queries.
Example 1:
Input: n = 5, queries = [[2,4],[0,2],[0,4]]
Output: [3,2,1]
Explanation:

After the addition of the road from 2 to 4, the length of the shortest path from 0 to 4 is 3.

After the addition of the road from 0 to 2, the length of the shortest path from 0 to 4 is 2.

After the addition of the road from 0 to 4, the length of the shortest path from 0 to 4 is 1.
Example 2:
Input: n = 4, queries = [[0,3],[0,2]]
Output: [1,1]
Explanation:

After the addition of the road from 0 to 3, the length of the shortest path from 0 to 3 is 1.

After the addition of the road from 0 to 2, the length of the shortest path remains 1.
Constraints:
3 <= n <= 1051 <= queries.length <= 105queries[i].length == 20 <= queries[i][0] < queries[i][1] < n1 < queries[i][1] - queries[i][0]- There are no repeated roads among the queries.
- There are no two queries such that
i != jandqueries[i][0] < queries[j][0] < queries[i][1] < queries[j][1].
class Solution { /** 关键点: There are no two queries such that queries[i][0] < queries[j][0] < queries[i][1] < queries[j][1]. 在query不会出现类似: [1,5],[3,6] 这样的情况下, 我们可以初始化集合为所有的点与它的下一个点(实际不需要刻意存)都组成了edge并且存在set中 遇到新的query [start,end] 1. 如果存在start和end,那么直接start和end中间的的点都删除 2. 如果不存在 start 或者 end,说明这段已经被“短路”掉,直接跳过 那么最短path即为set中元素个数 为了加快遍历并删除start,end中的点,可以使用sortedset,即treeset 时间复杂度不太好计算: 设queries = M, cities = N O(N) + O(M*Log(N)*Log(N)) ?? */ public int[] shortestDistanceAfterQueries(int n, int[][] queries) { // define map, to store all TreeSet<Integer> set = new TreeSet<>(); for(int i = 0; i < n; i++) {//O(N) set.add(i); } //0,1,2,3,4 int[] result = new int[queries.length]; for(int i = 0; i < queries.length; i++) { //O(M) int start = queries[i][0], end = queries[i][1]; // 如果存在start和end,那么remove其中的点 if(set.contains(start) && set.contains(end)) {// O(Log(N)) while(true) { Integer next = set.ceiling(start + 1);// O(Log(N)) if(next == null || next >= end) break; set.remove(next); } } result[i] = set.size() - 1; } return result; } }

浙公网安备 33010602011771号