AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题 / 79490590
Accepted
CodeCrusader
CodeCrusader
Asked: 2025-03-07 04:17:07 +0800 CST2025-03-07 04:17:07 +0800 CST 2025-03-07 04:17:07 +0800 CST

找到排序顺序的最少操作

  • 772

任务描述为:

我有一个从 1 到 n 的不同数字数组,例如 arr = [5, 3, 4, 1, 2]

将名为 order 的变量初始化为 1,现在从左到右遍历数组并查找与变量 order 匹配的元素,如果找到则增加 order 并向前移动。换句话说,我们可以说将名为 order 的变量初始化为 1,因此首先从左到右遍历数组并查看 1 在数组中出现的位置,然后将 order 增加到 2,然后在数组中向前移动并查找 2,如果找到则将 order 增加到 3。像上面那样从左到右迭代称为操作

当 arr = [5,3,4,1,2] 时,从左到右依次遍历,当找到 arr[3] 时,order 的值从 1 变为 2,当找到 arr[4] 时,order 的值从 2 变为 3

重复上述步骤,直到变量阶达到值n。重复的次数称为操作。

因此当 arr [ 5,3,4,1,2] 时,所需的最少操作数为 3

import java.util.*;

class Main {
    public static int solve(List<Integer> arr) {
        int n = arr.size();
        int order = 0; // Number of sorted items found
        int operations = 0;  // Count of full array scan
        
        while (sortedCount < n) {
            order++;
            for (int i = 0; i < n; i++) {
                if (arr.get(i) == order + 1) {
                    order++;
                }
            }
        }        
        return operations;
    }

    public static void main(String[] args) {
        System.out.println(solve(Arrays.asList(5, 3, 4, 1, 2))); // Output: 3
        System.out.println(solve(Arrays.asList(3,1,4,2,5))); // Output: 2
        System.out.println(solve(Arrays.asList(1,2,3,4))); // Output: 1
        System.out.println(solve(Arrays.asList(2,1))); // Output: 2
    }
}

我的代码运行时间为 O(n^2),我们如何才能以更低的时间复杂度解决这个问题

java
  • 3 3 个回答
  • 89 Views

3 个回答

  • Voted
  1. Best Answer
    maraca
    2025-03-07T10:24:23+08:002025-03-07T10:24:23+08:00

    以下算法在 O(n) 中解决问题:

    public static int solve(List<Integer> arr) {
        int operations = 0;
        Set<Integer> visited = new HashSet<>();
        for (int i : arr) {
            if (!visited.contains(i - 1))
               operations++;
            visited.add(i);
        }
        return operations;
    }
    

    这个想法是,如果你之前没有看到数字 - 1,那么你必须在下一次传递中得到它,所以这是计算所有必需的传递。你可以使用布尔数组代替哈希集来提高性能,但复杂性是一样的。

    • 3
  2. nhuquynh
    2025-03-07T10:48:09+08:002025-03-07T10:48:09+08:00

    这是我的想法

        public static int solve(List<Integer> arr) {
            int n = arr.size();
            Map<Integer, Integer> indexMap = new HashMap<>();
            
           
            for (int i = 0; i < n; i++) {
                indexMap.put(arr.get(i), i);
            }
            // we store
            //5 -> 0  
            //3 -> 1  
            //4 -> 2  
            //1 -> 3  
            //2 -> 4  
            
            int operations = 1; //we start from 1
            for (int i = 2; i <= n; i++) { // and try to find each next number (2, 3, 4, ...).
                //If index of i is bigger than index of (i - 1), we’re still good, Numbers are appearing in increasing order
                if (indexMap.get(i) < indexMap.get(i - 1)) {
                    operations++; //BUT if index of i is smaller, that means we gotta restart our search (new operation needed).
                }
            }
            //One loop to build the map (O(n))
            //One loop to count operations (O(n))
            // => Total: O(n)
            return operations;
        }
    
    
    
    • 1
  3. HopefullyHelpful
    2025-03-07T04:50:34+08:002025-03-07T04:50:34+08:00

    如果数组包含数字 1 到 N,那么您可以按照所需的排序顺序打印数字 1 到 N,而无需查看数组。

    • -3

相关问题

  • Lock Condition.notify 抛出 java.lang.IllegalMonitorStateException

  • 多对一微服务响应未出现在邮递员中

  • 自定义 SpringBoot Bean 验证

  • Java 套接字是 FIFO 的吗?

  • 为什么不可能/不鼓励在服务器端定义请求超时?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    重新格式化数字,在固定位置插入分隔符

    • 6 个回答
  • Marko Smith

    为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会?

    • 2 个回答
  • Marko Smith

    VScode 自动卸载扩展的问题(Material 主题)

    • 2 个回答
  • Marko Smith

    Vue 3:创建时出错“预期标识符但发现‘导入’”[重复]

    • 1 个回答
  • Marko Smith

    具有指定基础类型但没有枚举器的“枚举类”的用途是什么?

    • 1 个回答
  • Marko Smith

    如何修复未手动导入的模块的 MODULE_NOT_FOUND 错误?

    • 6 个回答
  • Marko Smith

    `(表达式,左值) = 右值` 在 C 或 C++ 中是有效的赋值吗?为什么有些编译器会接受/拒绝它?

    • 3 个回答
  • Marko Smith

    在 C++ 中,一个不执行任何操作的空程序需要 204KB 的堆,但在 C 中则不需要

    • 1 个回答
  • Marko Smith

    PowerBI 目前与 BigQuery 不兼容:Simba 驱动程序与 Windows 更新有关

    • 2 个回答
  • Marko Smith

    AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String”

    • 1 个回答
  • Martin Hope
    Fantastic Mr Fox msvc std::vector 实现中仅不接受可复制类型 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant 使用 chrono 查找下一个工作日 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor 构造函数的成员初始化程序可以包含另一个成员的初始化吗? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský 为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul C++20 是否进行了更改,允许从已知绑定数组“type(&)[N]”转换为未知绑定数组“type(&)[]”? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann 为什么 {2,3,10} 和 {x,3,10} (x=2) 的顺序不同? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller 在 5.2 版中,bash 条件语句中的 [[ .. ]] 中的分号现在是可选的吗? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench 为什么双破折号 (--) 会导致此 MariaDB 子句评估为 true? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng 为什么 `dict(id=1, **{'id': 2})` 有时会引发 `KeyError: 'id'` 而不是 TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String” 2024-03-20 03:12:31 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve