Created
November 22, 2016 16:21
-
-
Save tmosest/ff988f77b28bf0de984bb2b6741950b0 to your computer and use it in GitHub Desktop.
Almost working solution to Fraudulent Activity Notifications
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.Arrays; | |
import java.util.Comparator; | |
import java.util.PriorityQueue; | |
import java.util.Scanner; | |
/** | |
* Algorithms -> Sorting -> Fraudulent Activity Notifications | |
* Medium | |
*/ | |
public class FraudulentActivityNotifications { | |
public static void main(String[] args) { | |
boolean debugMode = false; | |
Scanner in = new Scanner(System.in); | |
int days = in.nextInt(); | |
int daysNeeded = in.nextInt(); | |
RunningMedian runningMedian = new RunningMedianWithDayLimits(daysNeeded); | |
int[] bankTransactions = new int[days]; | |
for(int i = 0; i < days; i++) { | |
bankTransactions[i] = in.nextInt(); | |
if(debugMode) | |
System.out.println("Added transacion: " + i + " : " + bankTransactions[i]); | |
} | |
in.close(); | |
int notification = 0; | |
if(debugMode) | |
System.out.println("Set nofitications to zero"); | |
for(int i = 0; i < days - 1; i++) { | |
double median = runningMedian.getMedian(bankTransactions[i]); | |
if(debugMode) | |
System.out.println("median for day " + i + " : " + median); | |
if(i >= daysNeeded - 1) { | |
double threshold = median * 2; | |
if(debugMode) { | |
System.out.println("Threshold for day " + i + " : " + threshold); | |
System.out.println("Checking against: " + bankTransactions[i + 1]); | |
} | |
if(bankTransactions[i + 1] >= threshold) { | |
notification++; | |
} | |
} | |
} | |
System.out.println(notification); | |
} | |
// start class RunningMedian | |
private static class RunningMedian | |
{ | |
PriorityQueue<Integer> upperQueue; | |
PriorityQueue<Integer> lowerQueue; | |
public RunningMedian() | |
{ | |
lowerQueue=new PriorityQueue<Integer>( | |
20,new Comparator<Integer>() | |
{ | |
@Override | |
public int compare(Integer o1, Integer o2) | |
{ | |
return -o1.compareTo(o2); | |
} | |
}); | |
upperQueue=new PriorityQueue<Integer>(); | |
upperQueue.add(Integer.MAX_VALUE); | |
lowerQueue.add(Integer.MIN_VALUE); | |
} | |
public double getMedian(int num) | |
{ | |
//adding the number to proper heap | |
if(num>=upperQueue.peek()) | |
upperQueue.add(num); | |
else | |
lowerQueue.add(num); | |
//balancing the heaps | |
if(upperQueue.size()-lowerQueue.size()==2) | |
lowerQueue.add(upperQueue.poll()); | |
else if(lowerQueue.size()-upperQueue.size()==2) | |
upperQueue.add(lowerQueue.poll()); | |
//returning the median | |
if(upperQueue.size()==lowerQueue.size()) | |
return(upperQueue.peek()+lowerQueue.peek())/2.0; | |
else if(upperQueue.size()>lowerQueue.size()) | |
return upperQueue.peek(); | |
else | |
return lowerQueue.peek(); | |
} | |
} //end class RunningMedian | |
// start class RunningMedian with day limits | |
private static class RunningMedianWithDayLimits extends RunningMedian | |
{ | |
private int count = 0; | |
private int numberOfDays = 0; | |
private int[] toRemove; | |
public RunningMedianWithDayLimits(int numberOfDays) | |
{ | |
this.numberOfDays = numberOfDays; | |
toRemove = new int[numberOfDays]; | |
lowerQueue=new PriorityQueue<Integer>( | |
20,new Comparator<Integer>() | |
{ | |
@Override | |
public int compare(Integer o1, Integer o2) | |
{ | |
return -o1.compareTo(o2); | |
} | |
}); | |
upperQueue=new PriorityQueue<Integer>(); | |
upperQueue.add(Integer.MAX_VALUE); | |
lowerQueue.add(Integer.MIN_VALUE); | |
} | |
public double getMedian(int num) | |
{ | |
//adding the number to proper heap | |
if(num>=upperQueue.peek()) | |
upperQueue.add(num); | |
else | |
lowerQueue.add(num); | |
//increment count | |
count++; | |
//balancing the heaps | |
if(upperQueue.size()-lowerQueue.size()==2) | |
lowerQueue.add(upperQueue.poll()); | |
else if(lowerQueue.size()-upperQueue.size()==2) | |
upperQueue.add(lowerQueue.poll()); | |
//remove elements if needed | |
if(count > numberOfDays - 1) { | |
if(count != 0) { | |
int indexToRemove = (count) % numberOfDays; | |
if(toRemove[indexToRemove]>=upperQueue.peek()) | |
upperQueue.remove(toRemove[indexToRemove]); | |
else | |
lowerQueue.remove(toRemove[indexToRemove]); | |
} | |
} | |
toRemove[count % numberOfDays] = num; | |
//returning the median | |
if(upperQueue.size()==lowerQueue.size()) | |
return(upperQueue.peek()+lowerQueue.peek())/2.0; | |
else if(upperQueue.size()>lowerQueue.size()) | |
return upperQueue.peek(); | |
else | |
return lowerQueue.peek(); | |
} | |
public void printQues() | |
{ | |
System.out.println("Lower"); | |
for(int num : lowerQueue) { | |
System.out.print(num + " "); | |
} | |
System.out.println(""); | |
System.out.println("Upper"); | |
for(int num : upperQueue) { | |
System.out.print(num + " "); | |
} | |
System.out.println(""); | |
} | |
} | |
// end class RunningMedian with day limits | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment