0

I have these two methods in java

  • public Int[] getFollows
  • public Int[] getFollowers

Where getfollows(user1) returns an array of users that user1 follows

and getfollowers(user1) returns an array of users that follow user1

My current data structure is an 2-d array so that I have

For every new follower of user1 I run followerArray[user1][followers++]=newFollower This means that getFollowers()will run in O(1) time as I just return followerArray[user1]

However the method getFollows() will require me to use two for loops to search through all of the arrays N times so will run in O(N^2).

Is there a way that I can decrease the time complexity of the method getFollows without sacrificing the speed of getFollowers()

user2962956
  • 163
  • 1
  • 1
  • 6

3 Answers3

2

You could use 2 Maps, one to keep track of followers and other for follows. It ensures constant look up time.

nitnamby
  • 404
  • 2
  • 8
2

Store the data in whatever data structure you like. That's very coarsely what a database will do. The important step is its indices. In particular you have

AnyDataStructure users; // supports get(userKey) operation for some userKey; e.g. array index, integer, etc.

And you need to create two indices that you will maintain for look up.

Map<UserKey, List<UserKey>> followers = new HashMap<>();
Map<UserKey, List<UserKey>> follows = new HashMap<>();

yes, it's redundant. Indices are redundant. Note they're not that redundant though, in that they don't store the users duplicated again from scratch, just whatever key you use. You will have to maintain these with AnyDataStructure, i.e. any time a user is added, deleted, or a follower is added or deleted, you will have to maintain the maps too.

Note those maps perhaps should just be member variables of the User class.

List<UserKey> followers;
List<UserKey> following;

So that updating followers/following just updates the users themselves. This may not be maintainable as you add more and more features, but by this point you almost certainly should be doing this in a bona fide relational or NoSQL database anyway.

djechlin
  • 59,258
  • 35
  • 162
  • 290
0

using HashSet can reduce order to O(n) :

HashMap<Integer, HashSet<Integer>>  follows;

Integer[] getFollows(int user) {
    HashSet<Integer> r = follows.get(user);
    return r.toArray(new Integer[r.size()]);
}

Integer[] getFollowers(int user) {
    ArrayList<Integer> a = new ArrayList<Integer>();
    for (Integer i : follows.keySet())
        if (follows.get(i).contains(user))
            a.add(i);
    return a.toArray(new Integer[a.size()]);
}
Farvardin
  • 5,336
  • 5
  • 33
  • 54