1. 程式人生 > 程式設計 >最長的可整合子陣列的長度

最長的可整合子陣列的長度

題目描述

先給出可整合陣列的定義:如果一個陣列在排序之後,每相鄰兩個數的絕對值都為1,或者該陣列長度為1,則該陣列為可整合陣列。例如[5,3,4,6,2]排序後為[2,5,6],符合每相鄰兩個數差的絕對值都為1,所以這個陣列為可整合陣列。給定一個陣列arr,請返回其中最大可整合子陣列的長度。例如[5,2,3]的最大可整合子陣列為[5,4],所以請返回5
[要求]時間複雜度為O(n^2),空間複雜度為O(n)

輸入示例
7
5 5 3 2 6 4 3
輸出
5
複製程式碼

解題思路分析

  • 首先本題題意描述可整合陣列的定義得清晰,而且題目也給了提示了,其實得先給陣列進行排序
  • 使用快排排完序之後呢,我們就要考慮如何在排序陣列中給找出最長的可整合子陣列的長度,這裡可以使用雙指標法進行查詢(程式碼中有了詳細介紹了)

程式碼實現

public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = Integer.valueOf(scanner.nextLine());
        int[] nums = new int[n];
        String[] lines = scanner.nextLine().split(" ");
        for (int i = 0; i < n; i++) {
            nums[i] = Integer.valueOf(lines[i]);
        }
        quickSort(nums,0
,n - 1); System.out.println(getAns(nums,n)); } //快排 private static void quickSort(int[] nums,int left,int right) { int base = nums[left],i = left,j = right; while (i < j) { while (nums[j] >= base && i < j) { j--; } if
(i < j) { nums[i] = nums[j]; i++; while (nums[i] <= base && i < j) { i++; } if (i < j) { nums[j] = nums[i]; j--; } } } nums[i] = base; if (left < (i - 1)) { quickSort(nums,left,i - 1); } if ((j + 1) < right) { quickSort(nums,j + 1,right); } } private static int getAns(int[] nums,int n) { /** * 初始長度肯定為 1 ,因為最長子整合陣列中至少會有一個元素,然後定義兩個下標 i 為前面這個下標,j 為後面這個下標 */ int length = 1,i = 0,j = 1; while (i < n && j < n) {//停止條件為 i 和 j 都不越界 if (j < n - 1) {//首先得判斷 j 是否到了陣列的最後一個位置,在這裡判斷是為了後面不會丟擲越界異常 if (nums[j] == nums[j + 1]) {//如果 j 與 j 後面這個數字相等時,就可以直接將 j 定位到後面這個數字,此時 i 不變 j++; } else if (nums[i] == (nums[j] - 1)) {// 當前 i 和 j 指向的數字符合題目要求 length++;//長度 +1 j++;// j 後移一位 i = j - 1;//注意這裡需要始終保證 i 和 j 相鄰 } else {// 當前 j 和 i 指向的數字不符合題目要求 j++;// j 後移一位 i = j - 1;//注意這裡需要始終保證 i 和 j 相鄰 } } else {// j 指向了最後一個數字 if (nums[i] == (nums[j] - 1)) {//如果此時符合要求 length++;//長度 +1 j++;// j 後移一位 i = j - 1;//注意這裡需要始終保證 i 和 j 相鄰 } else {//不符合要求 j++;// j 後移一位 i = j - 1;//注意這裡需要始終保證 i 和 j 相鄰 } } } return length; } 複製程式碼