阿里研发岗 0530笔试真题 - 数组中的沉默元素计数

数组中的沉默元素计数

阿里研发岗 0530笔试 第一题

题目内容

TkTkTk 有一个长度为 nnn 的数组 {a1,a2,...,ana_1, a_2, ..., a_na1,a2,...,an},对于下标满足 1<i<n1 < i < n1<i<n 的元素 aia_iai,若其左侧所有元素的最大值到它的距离,等于其右侧所有元素的最大值到它的距离,那么这个数字就是沉默的。若左侧(或右侧)区域存在多个数值相等的最大值,则选择其中与 iii 距离最近的下标计算距离。

TkTkTk 想知道数组中一共有多少位置不同的沉默的数字,请输出这个值。

输入描述

每个测试文件均包含多组测试数据。

  • 第一行输入一个整数 T(1≤T≤104)T(1 ≤ T ≤ 10^4)T(1≤T≤104),代表数据组数。
  • 每组测试数据描述如下:
  1. 第一行输入一个整数 n(3≤n≤2×105)n(3 ≤ n ≤ 2 × 10^5)n(3≤n≤2×105),表示数组长度。
  2. 第二行输入 nnn 个整数 a1,a2,...,an(1≤ai≤109)a_1, a_2, ..., a_n(1 ≤ a_i ≤ 10^9)a1,a2,...,an(1≤ai≤109),表示数组 a
  • 保证单个测试文件的 nnn 之和不超过 2×1052 × 10^52×105。

输出描述

对于每一组测试数据,新起一行,输出一个整数表示结果。

样例1

输入

复制代码
2
3
1 1 1
5
1 4 4 5 2

输出

复制代码
1
2

题解和思路

思路

实现思路:模拟

  1. 定义leftright分别记录当前元素位置左侧最大值位置和右侧最大值位置。、
  2. 计算leftright对应值,以left为例,定义maxValue = -1maxValueIndex = -1分贝表示对应侧最大值和对应位置,从前往后进行遍历,对于位置i的处理逻辑如下:
    • 如果maxValueIndex != -1, 更新left[i] = maxValueIndex
    • 尝试更新maxValueIndex, 如果a[i] >= maxValue, 更新maxValueIndex = i , maxValue = a[i]
  • 统计每组沉默数字,从前往后遍历如果abs(i - left[i]) == abs(i - right[i])对应沉默数字+1.前提left[i] != -1 and right[i] != -1

C++

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    int T;
    cin >> T;
    while (T--) {
        int n;
        cin >> n;
        vector<int> a(n);
        for (int i = 0; i < n; i++) {
            cin >> a[i];
        }
        // 记录左侧最大值位置
        vector<int> left(n , -1);
        // 记录右侧最大值位置
        vector<int> right(n, - 1);
        
        // 处理左侧
        int maxValue = -1;
        int maxValueIndex = -1;
        for (int i = 0; i < n; i++) {
            int val = a[i];
            if (maxValueIndex != -1) {
                left[i] = maxValueIndex;
            }
            if (maxValue <= val) {
                maxValue = val;
                maxValueIndex = i;
            }
        }
        
        // 处理右侧
        maxValue = -1;
        maxValueIndex = -1;
        for (int i = n - 1; i >= 0; i--) {
            int val = a[i];
            if (maxValueIndex != -1) {
                right[i] = maxValueIndex;
            }
            if (maxValue <= val) {
                maxValue = val;
                maxValueIndex = i;
            }            
        }
        
        int count = 0;
        for (int i = 0; i < n; i++) {
            if (left[i] == -1 || right[i] == -1) {
                continue;
            }
            if (abs(i - left[i]) == abs(i - right[i])) {
                count++;
            }
        }
        cout << count << endl;
    }
    return 0;
}

Java

java 复制代码
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int T = sc.nextInt();

        while (T-- > 0) {
            int n = sc.nextInt();

            int[] a = new int[n];
            for (int i = 0; i < n; i++) {
                a[i] = sc.nextInt();
            }

            // 记录左侧最大值位置
            int[] left = new int[n];
            Arrays.fill(left, -1);

            // 记录右侧最大值位置
            int[] right = new int[n];
            Arrays.fill(right, -1);

            // 处理左侧
            int maxValue = -1;
            int maxValueIndex = -1;

            for (int i = 0; i < n; i++) {
                int val = a[i];

                if (maxValueIndex != -1) {
                    left[i] = maxValueIndex;
                }

                if (maxValue <= val) {
                    maxValue = val;
                    maxValueIndex = i;
                }
            }

            // 处理右侧
            maxValue = -1;
            maxValueIndex = -1;

            for (int i = n - 1; i >= 0; i--) {
                int val = a[i];

                if (maxValueIndex != -1) {
                    right[i] = maxValueIndex;
                }

                if (maxValue <= val) {
                    maxValue = val;
                    maxValueIndex = i;
                }
            }

            int count = 0;

            for (int i = 0; i < n; i++) {
                if (left[i] == -1 || right[i] == -1) {
                    continue;
                }

                if (Math.abs(i - left[i]) == Math.abs(i - right[i])) {
                    count++;
                }
            }

            System.out.println(count);
        }
    }
}

python

python 复制代码
t = int(input())

for _ in range(t):
    n = int(input())
    a = list(map(int, input().split()))

    # 记录左侧最大值位置
    left = [-1] * n

    # 记录右侧最大值位置
    right = [-1] * n

    # 处理左侧
    max_value = -1
    max_value_index = -1

    for i in range(n):
        val = a[i]

        if max_value_index != -1:
            left[i] = max_value_index

        if max_value <= val:
            max_value = val
            max_value_index = i

    # 处理右侧
    max_value = -1
    max_value_index = -1

    for i in range(n - 1, -1, -1):
        val = a[i]

        if max_value_index != -1:
            right[i] = max_value_index

        if max_value <= val:
            max_value = val
            max_value_index = i

    count = 0

    for i in range(n):
        if left[i] == -1 or right[i] == -1:
            continue

        if abs(i - left[i]) == abs(i - right[i]):
            count += 1

    print(count)

Javascript

js 复制代码
const readline = require('readline');

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

const input = [];

rl.on('line', line => {
    input.push(...line.trim().split(/\s+/).map(Number));
});

rl.on('close', () => {
    let idx = 0;

    let T = input[idx++];

    while (T--) {
        const n = input[idx++];

        const a = [];
        for (let i = 0; i < n; i++) {
            a.push(input[idx++]);
        }

        // 记录左侧最大值位置
        const left = new Array(n).fill(-1);

        // 记录右侧最大值位置
        const right = new Array(n).fill(-1);

        // 处理左侧
        let maxValue = -1;
        let maxValueIndex = -1;

        for (let i = 0; i < n; i++) {
            const val = a[i];

            if (maxValueIndex !== -1) {
                left[i] = maxValueIndex;
            }

            if (maxValue <= val) {
                maxValue = val;
                maxValueIndex = i;
            }
        }

        // 处理右侧
        maxValue = -1;
        maxValueIndex = -1;

        for (let i = n - 1; i >= 0; i--) {
            const val = a[i];

            if (maxValueIndex !== -1) {
                right[i] = maxValueIndex;
            }

            if (maxValue <= val) {
                maxValue = val;
                maxValueIndex = i;
            }
        }

        let count = 0;

        for (let i = 0; i < n; i++) {
            if (left[i] === -1 || right[i] === -1) {
                continue;
            }

            if (Math.abs(i - left[i]) === Math.abs(i - right[i])) {
                count++;
            }
        }

        console.log(count);
    }
});

Go

go 复制代码
package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	in := bufio.NewReader(os.Stdin)

	var T int
	fmt.Fscan(in, &T)

	for ; T > 0; T-- {
		var n int
		fmt.Fscan(in, &n)

		a := make([]int, n)
		for i := 0; i < n; i++ {
			fmt.Fscan(in, &a[i])
		}

		// 记录左侧最大值位置
		left := make([]int, n)

		// 记录右侧最大值位置
		right := make([]int, n)

		for i := 0; i < n; i++ {
			left[i] = -1
			right[i] = -1
		}

		// 处理左侧
		maxValue := -1
		maxValueIndex := -1

		for i := 0; i < n; i++ {
			val := a[i]

			if maxValueIndex != -1 {
				left[i] = maxValueIndex
			}

			if maxValue <= val {
				maxValue = val
				maxValueIndex = i
			}
		}

		// 处理右侧
		maxValue = -1
		maxValueIndex = -1

		for i := n - 1; i >= 0; i-- {
			val := a[i]

			if maxValueIndex != -1 {
				right[i] = maxValueIndex
			}

			if maxValue <= val {
				maxValue = val
				maxValueIndex = i
			}
		}

		count := 0

		for i := 0; i < n; i++ {
			if left[i] == -1 || right[i] == -1 {
				continue
			}

			if abs(i-left[i]) == abs(i-right[i]) {
				count++
			}
		}

		fmt.Println(count)
	}
}

func abs(x int) int {
	if x < 0 {
		return -x
	}
	return x
}
相关推荐
无限码力7 小时前
阿里算法岗 0530笔试真题 - 荆棘林的最优砍断计划
算法·阿里笔试真题·阿里机试真题·阿里算法岗笔试真题·阿里巴巴笔试真题
无限码力8 小时前
阿里算法岗 0530笔试真题 - 寻找满足条件的最优子序列
算法·阿里笔试真题·阿里机试真题·阿里算法岗笔试真题·阿里算法题