简体   繁体   English

实现树形数据结构以查找和搜索最大的人

[英]implementing tree data structure for finding and searching largest people in a line

I've encountered this problem:我遇到过这个问题:

some people (with specific id ) want to stand in front of the mirror and no one goes out of the way: the problem gives us the id and height of each person:有些人(具有特定id )想站在镜子前,没有人挡道:问题给了我们每个人的 id 和身高:

 200 4000
 50 1200

which the first number indicates the id and the second one is the height (yes these people are huge.) you can see yourself in the mirror only if you are taller than people in front of you.第一个数字表示身份证,第二个数字是身高(是的,这些人很大。)只有当你比你面前的人高时,你才能在镜子里看到自己。 The order of standing is the same as the order of inputs.站立顺序与输入顺序相同。 after some amount of inputs the problem request whether or not some person with some id can see himself or not?经过一定数量的输入后,问题请求具有某些身份的人是否可以看到自己? there are two commands: one for adding to the line**+** and one for checking that id**:** so: Input: 100 1000 50 1000 100 50 Output: YES NO有两个命令:一个用于添加到行**+**,另一个用于检查 id**:** 所以:输入:100 1000 50 1000 100 50 输出:YES NO

100 can see himself but 50 can not since someone with same height is standing in front of him also if n is the number of command: 100人可以看到自己,但50人看不到,因为同样身高的人站在他面前,如果 n 是命令的数量:
also:还:
no one can change its place and at any time in the n input line the problem can request if a person can see it self or not using this command:没有人可以改变它的位置,并且在 n 输入行中的任何时候,问题都可以请求一个人是否可以看到它自己或不使用此命令:

 person's id

The time limit on the problem is one second so I believe we need an O(nlogn) answer.这个问题的时间限制是一秒,所以我相信我们需要一个O(nlogn)的答案。
My solution so far: if we could have an tree with each node not only containing the id and the height but the max height of every body in its sub-tree the it would be very easy to find the answer because we add each node to the tree based on the persons height.到目前为止我的解决方案:如果我们可以有一棵树,每个节点不仅包含 id 和高度,还包含其子树中每个主体的最大高度,那么很容易找到答案,因为我们将每个节点添加到树基于人的身高。 I believe red and black trees would be a good data structure here.我相信红树和黑树在这里会是一个很好的数据结构。 so for instance I can use TreeSet in java which uses red-black trees.所以例如我可以在 java 中使用TreeSet ,它使用红黑树。


My problems:我的问题:

First of all I'm not really sure that my way of thinking is right and what date structure should I use?首先,我不确定我的思维方式是否正确,我应该使用什么日期结构?
second How should I implement this solution (if it's right) in code?第二我应该如何在代码中实现这个解决方案(如果它是正确的)? The language is not very important but it would be great if you could help using java or c++.语言不是很重要,但如果您能帮助使用 java 或 c++,那就太好了。 I need some hint on how to actually do this algorithm in fastest way我需要一些关于如何以最快的方式实际执行此算法的提示


thanks very much非常感谢

Actually, with these requirements, this can be solved in O(1).实际上,有了这些要求,这可以在 O(1) 中解决。

The algorithm:算法:

We keep a heightNeededToSeeSelf variable.我们保留一个heightNeededToSeeSelf变量。

  • Person 1 (height = h[0]) always sees themselves as there is no one in front of them.人 1 (height = h[0]) 总是看到自己,因为他们面前没有人。
  • neededHeightToSeeSelf = h[0]
  • Person 2 (height = h[1]) can see herself if h[1] > neededHeightToSeeSelf .如果h[1] > neededHeightToSeeSelf ,人 2 (height = h[1]) 可以看到自己。
  • if h[1] > neededHeightToSeeSelf :如果h[1] > neededHeightToSeeSelf

    neededHeightToSeeSelf = h[1]

  • Store a pointer to the id of the person in the line and use it to find the person's status in case asked.存储指向行中人员 id 的指针,并在询问时使用它来查找人员的状态。
  • Continue for person 3,4,...n until user quits.继续人员 3,4,...n 直到用户退出。

That's it.而已。

Java code: Java代码:

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    Map<String, Integer> idmap = new HashMap<>();
    List<Boolean> canSeeSelf = new ArrayList<>();
    int neededHeightToSeeSelf = 0;
    while(sc.hasNextLine()) {
        String[] line = sc.nextLine().split(" ");
        if(line[0].equals("+")) {
            int personHeight = Integer.parseInt(line[2]);
            if(personHeight > neededHeightToSeeSelf) {
                canSeeSelf.add(true);
                neededHeightToSeeSelf = personHeight;
            }
            else {
                canSeeSelf.add(false);
            }
            idmap.put(line[1], canSeeSelf.size() - 1);
        } else if(line[0].equals("?")) {
            int index = idmap.get(line[1]);
            System.out.println(canSeeSelf.get(index));
        } else {
            System.out.println("Quitting...");
            System.exit(1);
        }
    }
}

idmap simply stores a pointer to the index of the person in the line. idmap只是存储指向行中人员索引的指针。 This code is only to show the O(1) solution and is not a perfect solution.此代码仅显示 O(1) 解决方案,并不是一个完美的解决方案。 The indirection can be removed so idmap can directly answer the true/false question.可以删除间接性,因此idmap可以直接回答真/假问题。

Test input:测试输入:

+ 100 1000
+ 50 1000
+ 101 500
+ 102 100
? 102
false
? 100
true
? 50
false
+ 103 2000
? 103
true
end
Quitting...

Can height of the person be updated?可以更新人的身高吗? Assuming, update of height is not required and the input is given in the order of standing, as you read, check if person height is higher than all other persons added so far(ie currentMaxHeight).假设不需要更新高度,并且输入按站立顺序给出,当您阅读时,请检查人的身高是否高于到目前为止添加的所有其他人(即 currentMaxHeight)。

Below is one of the possible solution using Hashmap of Person and Boolean value.以下是使用 Person 的 Hashmap 和 Boolean 值的可能解决方案之一。 This is just a sample code to demonstrate and test.这只是一个示例代码来演示和测试。

Person class with id and height, please take closer look at the equals() and hashCode().具有 id 和高度的人 class,请仔细查看 equals() 和 hashCode()。 public class Person {公共class人{

private int id;
private int height;

public Person(int id, int height) {
    this.id = id;
    this.height = height;
}

public Person(int id) {
    this.id = id;
}

public int getId() {
    return id;
}

public int getHeight() {
    return height;
}

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Person person = (Person) o;
    return id == person.id;
}

@Override
public int hashCode() {
    return Objects.hash(id);
}

@Override
public String toString() {
    return "Person{" +
            "id=" + id +
            ", height=" + height +
            '}';
}
}

TallestPerson class to add person and verify can see self. TallestPerson class 添加人并验证可以看到自己。

  public class TallestPerson {

    public static void main(String[] args) {

    List<Person> personList = new ArrayList<>();
    personList.add(new Person(100, 100));
    personList.add(new Person(101, 50));
    personList.add(new Person(102, 200));
    personList.add(new Person(103, 200));
    personList.add(new Person(104, 100));
    personList.add(new Person(105, 300));

    addPerson(personList);
    System.out.println(canSeeSelf(100));
    System.out.println(canSeeSelf(101));
    System.out.println(canSeeSelf(102));
    System.out.println(canSeeSelf(103));
    System.out.println(canSeeSelf(104));
    System.out.println(canSeeSelf(105));
}

static int currentMaxHeight = Integer.MIN_VALUE;
static Map<Person, Boolean> personMap = new HashMap<>();

static public void addPerson(List<Person> personList) {
    for (Person person : personList) {
        addPerson(person);
    }
}

static public void addPerson(Person person) {
    addPerson(person.getId(), person.getHeight());
}

static public void addPerson(int id, int height) {
    if (height > currentMaxHeight) {
        personMap.put(new Person(id, height), true);
        currentMaxHeight = height;
    } else {
        personMap.put(new Person(id, height), false);
    }
}

static public boolean canSeeSelf(int id) {
    return personMap.get(new Person(id));
}
}

Output Output

 true
 false
 true
 false
 false
 true

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM