Concise 21-Line C# by using 2 Sorted Sets
public class MedianFinder {\n        private int counter = 0;\n        private SortedSet<int[]> setLow = new SortedSet<int[]>(Comparer<int[]>.Create((a, b) => a
    public class MedianFinder {\n        private int counter = 0;\n        private SortedSet<int[]> setLow = new SortedSet<int[]>(Comparer<int[]>.Create((a, b) => a[0] == b[0] ? a[1] - b[1] : a[0] - b[0]));\n        private SortedSet<int[]> setHigh = new SortedSet<int[]>(Comparer<int[]>.Create((a, b) => a[0] == b[0] ? a[1] - b[1] : a[0] - b[0]));\n        public void AddNum(int num) {\n            int[] newNum = new int[2]{num, counter++};\n            if(setLow.Count == setHigh.Count){\n                if(setLow.Count == 0 || newNum[0] <= setLow.Max[0]) setLow.Add(newNum);\n                else{\n                    setHigh.Add(newNum);\n                    setLow.Add(setHigh.Min);\n                    setHigh.Remove(setHigh.Min);\n                }\n            }\n            else if(newNum[0] <= setLow.Max[0]){\n                setLow.Add(newNum);\n                setHigh.Add(setLow.Max);\n                setLow.Remove(setLow.Max);\n            }\n            else setHigh.Add(newNum);\n        }\n        // return the median of current data stream\n        public double FindMedian() {\n            if(setLow.Count == 0) return 0;\n            if(setLow.Count == setHigh.Count) return (setLow.Max[0] + setHigh.Min[0]) / 2d;\n            else return setLow.Max[0];\n        }\n    }
[]