【问题标题】:Finding next occurance for each element in array in O(n)在 O(n) 中查找数组中每个元素的下一次出现
【发布时间】:2018-01-18 08:10:00
【问题描述】:

假设我有一个这样的数组:[ 1, 2, 3, 4, 5, 6, 1]

我想获得类似 1 ==> 6 的输出(对于元素 1(0th 索引,匹配在索引 6 处找到)

这意味着对于第 0th 元素,下一个匹配项将在第 6 个索引处找到。

如果输入为[4,6,4,6],则输出为 4 ==> 2 和 6 ==> 3

因为 4 的第一个匹配项在索引 2(即 4)处找到,而 6 的第一个匹配项(2nd 元素)在 3rd 索引处找到

如果时间复杂度为 O(n2),则解决方案非常简单。我试图使用堆栈在 O(n) 中找到具有此代码的下一个最大元素。但是我找不到对下一个相等元素执行相同操作的方法。

import java.util.Scanner;
import java.util.Stack;

public class NextGreatestElement {
    public static void main(String[] args) {
        int[] inp = {1,4,6,2,39};
        Stack<Integer> stack = new Stack<>();
        stack.push(inp[0]);
        for (int i = 1; i < inp.length; i++) {
            int element = inp[i];
            if (element > stack.peek()) {
                System.out.println(stack.peek() + " ==> " + element);
                stack.pop();
                while (!stack.isEmpty()) {
                    System.out.println(stack.pop() + " ==> " + element);
                }
                stack.push(element);
            } else if (element < stack.peek()) {
                stack.push(element);
            }
        }
        while (!stack.isEmpty()) System.out.println(stack.pop() + " ==> " + (-1));
    }
}

即使是算法也足够了。我不需要代码。

【问题讨论】:

  • next greatest element 是什么意思?
  • 对于这个输入 [1, 2, 3, 4, 5, 6, 1] 下一个最大的元素是 1 它是 2 和 2 它是 3 等等,对于六个什么都没有
  • 您可以实现的最佳复杂度是 O(nlogn),使用快速排序对数组进行排序,然后遍历它以找到数组中没有更大后继的元素。
  • @bharath 说真的,无法理解您的问题。请提供一组输入和输出
  • 不,我不想要所有重复值的索引。我只想要下一个重复的索引:/

标签: java arrays algorithm data-structures stack


【解决方案1】:

不可能用O(n) 中的堆栈来实现它。您可以使用HashMap 并从右到左迭代以保存最后一次出现的数字。它会给你O(n)平均情况时间复杂度:

int[] inp = {1, 2, 3, 1, 2, 1, 3};
Map<Integer, Integer> h = new HashMap<>();
List<Integer> result = new ArrayList<>();

for (int i = inp.length - 1; i >= 0; --i) {
    int cur = inp[i];
    int next = -1;
    if (h.containsKey(cur)) {
        next = h.get(cur);
    }   
    h.put(cur, i);
    result.add(next);
}

for (int i = 0; i < inp.length; ++i) {
    System.out.println("Number " + inp[i] + " next occurence at index " + result.get(inp.length - i - 1));
}

可运行版本:http://ideone.com/i6Cx09

【讨论】:

【解决方案2】:

如果我没记错的话,你是想要元素还是获取数组中不止一次出现的元素。你可以这样做。

此解决方案将是 nlogn

  1. 对数组进行排序(升序)
  2. 循环数组然后比较
  3. 如果 a[i] == a[i+1] 那么 list.add(a[i]);

类似的东西 enter image description here

【讨论】:

    【解决方案3】:

    使用哈希图或哈希表

    从右到左遍历,第一次出现时将值输入到集合中

    collection_object.put(inp[i], ""+i)
    

    下次遇到的时候改一下就好了

    value = collection_object.get(inp[i])
    v = value.split("==>")
    value = v[0] + "==>" + i
    collection_object.put(inp[i], value)
    

    【讨论】:

    • 我听不懂你的回答
    • HashMap collection_object = new HashMap (); collection_object 是一个hashmap,在遍历输入数组时,当你第一次遇到一个元素时,只需输入该元素,其索引分别为键,值,下次遇到相同的元素时。使用第二个代码
    • 天啊,看完所有的cmets,我终于明白了你的问题,请在提问时说明。
    • 这不是我的错......有人编辑了我的问题,我认为它的语法更正,但它改变了整个含义
    • @bharath,你明白我的回答吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-24
    相关资源
    最近更新 更多