数组
哈希表
题目描述
一个数组 a
的 差绝对值的最小值 定义为:0 <= i < j < a.length
且 a[i] != a[j]
的 |a[i] - a[j]|
的 最小值 。如果 a
中所有元素都 相同 ,那么差绝对值的最小值为 -1
。
比方说,数组 [5,2 ,3 ,7,2]
差绝对值的最小值是 |2 - 3| = 1
。注意答案不为 0
,因为 a[i]
和 a[j]
必须不相等。
给你一个整数数组 nums
和查询数组 queries
,其中 queries[i] = [li , ri ]
。对于每个查询 i
,计算 子数组 nums[li ...ri ]
中 差绝对值的最小值 ,子数组 nums[li ...ri ]
包含 nums
数组(下标从 0 开始)中下标在 li
和 ri
之间的所有元素(包含 li
和 ri
在内)。
请你返回 ans
数组 ,其中 ans[i]
是第 i
个查询的答案。
子数组 是一个数组中连续的一段元素。
|x|
的值定义为:
如果 x >= 0
,那么值为 x
。
如果 x < 0
,那么值为 -x
。
示例 1:
输入: nums = [1,3,4,8], queries = [[0,1],[1,2],[2,3],[0,3]]
输出: [2,1,4,1]
解释: 查询结果如下:
- queries[0] = [0,1]:子数组是 [1 ,3 ] ,差绝对值的最小值为 |1-3| = 2 。
- queries[1] = [1,2]:子数组是 [3 ,4 ] ,差绝对值的最小值为 |3-4| = 1 。
- queries[2] = [2,3]:子数组是 [4 ,8 ] ,差绝对值的最小值为 |4-8| = 4 。
- queries[3] = [0,3]:子数组是 [1,3 ,4 ,8] ,差的绝对值的最小值为 |3-4| = 1 。
示例 2:
输入: nums = [4,5,2,2,7,10], queries = [[2,3],[0,2],[0,5],[3,5]]
输出: [-1,1,1,3]
解释: 查询结果如下:
- queries[0] = [2,3]:子数组是 [2,2] ,差绝对值的最小值为 -1 ,因为所有元素相等。
- queries[1] = [0,2]:子数组是 [4 ,5 ,2] ,差绝对值的最小值为 |4-5| = 1 。
- queries[2] = [0,5]:子数组是 [4 ,5 ,2,2,7,10] ,差绝对值的最小值为 |4-5| = 1 。
- queries[3] = [3,5]:子数组是 [2,7 ,10 ] ,差绝对值的最小值为 |7-10| = 3 。
提示:
2 <= nums.length <= 105
1 <= nums[i] <= 100
1 <= queries.length <= 2 * 104
0 <= li < ri < nums.length
解法
方法一
Python3 Java C++ Go TypeScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 class Solution :
def minDifference ( self , nums : List [ int ], queries : List [ List [ int ]]) -> List [ int ]:
m , n = len ( nums ), len ( queries )
pre_sum = [[ 0 ] * 101 for _ in range ( m + 1 )]
for i in range ( 1 , m + 1 ):
for j in range ( 1 , 101 ):
t = 1 if nums [ i - 1 ] == j else 0
pre_sum [ i ][ j ] = pre_sum [ i - 1 ][ j ] + t
ans = []
for i in range ( n ):
left , right = queries [ i ][ 0 ], queries [ i ][ 1 ] + 1
t = inf
last = - 1
for j in range ( 1 , 101 ):
if pre_sum [ right ][ j ] - pre_sum [ left ][ j ] > 0 :
if last != - 1 :
t = min ( t , j - last )
last = j
if t == inf :
t = - 1
ans . append ( t )
return ans
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 class Solution {
public int [] minDifference ( int [] nums , int [][] queries ) {
int m = nums . length , n = queries . length ;
int [][] preSum = new int [ m + 1 ][ 101 ] ;
for ( int i = 1 ; i <= m ; ++ i ) {
for ( int j = 1 ; j <= 100 ; ++ j ) {
int t = nums [ i - 1 ] == j ? 1 : 0 ;
preSum [ i ][ j ] = preSum [ i - 1 ][ j ] + t ;
}
}
int [] ans = new int [ n ] ;
for ( int i = 0 ; i < n ; ++ i ) {
int left = queries [ i ][ 0 ] , right = queries [ i ][ 1 ] + 1 ;
int t = Integer . MAX_VALUE ;
int last = - 1 ;
for ( int j = 1 ; j <= 100 ; ++ j ) {
if ( preSum [ right ][ j ] > preSum [ left ][ j ] ) {
if ( last != - 1 ) {
t = Math . min ( t , j - last );
}
last = j ;
}
}
if ( t == Integer . MAX_VALUE ) {
t = - 1 ;
}
ans [ i ] = t ;
}
return ans ;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 class Solution {
public :
vector < int > minDifference ( vector < int >& nums , vector < vector < int >>& queries ) {
int m = nums . size (), n = queries . size ();
int preSum [ m + 1 ][ 101 ];
for ( int i = 1 ; i <= m ; ++ i ) {
for ( int j = 1 ; j <= 100 ; ++ j ) {
int t = nums [ i - 1 ] == j ? 1 : 0 ;
preSum [ i ][ j ] = preSum [ i - 1 ][ j ] + t ;
}
}
vector < int > ans ( n );
for ( int i = 0 ; i < n ; ++ i ) {
int left = queries [ i ][ 0 ], right = queries [ i ][ 1 ] + 1 ;
int t = 101 ;
int last = -1 ;
for ( int j = 1 ; j <= 100 ; ++ j ) {
if ( preSum [ right ][ j ] > preSum [ left ][ j ]) {
if ( last != -1 ) {
t = min ( t , j - last );
}
last = j ;
}
}
if ( t == 101 ) {
t = -1 ;
}
ans [ i ] = t ;
}
return ans ;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 func minDifference ( nums [] int , queries [][] int ) [] int {
m , n := len ( nums ), len ( queries )
preSum := make ([][ 101 ] int , m + 1 )
for i := 1 ; i <= m ; i ++ {
for j := 1 ; j <= 100 ; j ++ {
t := 0
if nums [ i - 1 ] == j {
t = 1
}
preSum [ i ][ j ] = preSum [ i - 1 ][ j ] + t
}
}
ans := make ([] int , n )
for i := 0 ; i < n ; i ++ {
left , right := queries [ i ][ 0 ], queries [ i ][ 1 ] + 1
t , last := 101 , - 1
for j := 1 ; j <= 100 ; j ++ {
if preSum [ right ][ j ] - preSum [ left ][ j ] > 0 {
if last != - 1 {
if t > j - last {
t = j - last
}
}
last = j
}
}
if t == 101 {
t = - 1
}
ans [ i ] = t
}
return ans
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 function minDifference ( nums : number [], queries : number [][]) : number [] {
let m = nums . length ,
n = queries . length ;
let max = 100 ;
// let max = Math.max(...nums);
let pre : number [][] = [];
pre . push ( new Array ( max + 1 ). fill ( 0 ));
for ( let i = 0 ; i < m ; ++ i ) {
let num = nums [ i ];
pre . push ( pre [ i ]. slice ());
pre [ i + 1 ][ num ] += 1 ;
}
let ans = [];
for ( let [ left , right ] of queries ) {
let last = - 1 ;
let min = Infinity ;
for ( let j = 1 ; j < max + 1 ; ++ j ) {
if ( pre [ left ][ j ] < pre [ right + 1 ][ j ]) {
if ( last != - 1 ) {
min = Math . min ( min , j - last );
}
last = j ;
}
}
ans . push ( min == Infinity ? - 1 : min );
}
return ans ;
}
GitHub