twoSum Algorithm : How to improve this?

前端 未结 22 2526
礼貌的吻别
礼貌的吻别 2021-02-06 01:38

I felt like doing an algorithm and found this problem on leetcode

Given an array of integers, find two numbers such that they add up to a specific target num

22条回答
  •  眼角桃花
    2021-02-06 02:00

    Below you can find a solution in which the two numbers could be found in O(n log n) time:

    1- Sort the numbers in ascending (or descending) order             // O(n log n)
    
    2- Compute diff = target - item for each item                      // O(n) 
    
    3- For each calculated diff, look up the calculated value in the sorted items 
       using the Binary search algorithm                               // O(n log n) 
    

    A complete, working implementation in Java:

    import java.util.ArrayList;
    
    public class NumbersFinder {
    
        class Item{
            private int value;
            private int index;
    
            public Item(int value, int index){
                this.value = value;
                this.index = index;
            }
    
            public int getValue(){
                return value;
            }
    
            public int getIndex(){
                return index;
            }
        }
    
        public ArrayList find(int[] values, int target){      
            ArrayList items = new ArrayList();
            for(int i = 0; i < values.length; i++)
                items.add(new Item(values[i], i));
    
            items = quicksort(items);
            ArrayList diffs = computeDiffs(items, target);
    
            Item item1 = null;
            Item item2 = null;
    
            boolean found = false;
    
            for(int i = 0; i < diffs.get(i) && !found; i++){
                item1 = items.get(i);
                item2 = searchSortedItems(items, diffs.get(i), 0, items.size());
                found = item2 != null;
            }
            if(found){
                ArrayList result = new ArrayList();
                result.add(item1);
                result.add(item2);
                return result;
            }
            else
                return null;
        }
    
        // find "value" in the sorted array of "items" using Binary search in O(log n)
        private Item searchSortedItems(ArrayList items, Integer value, int lower, int upper) {
            if(lower > upper)
                return null;
            int middle = (lower + upper)/2;
            Item middleItem = items.get(middle);
            if(middleItem.getValue() == value)
                return middleItem;
            else if(middleItem.getValue() < value)
                return searchSortedItems(items, value, middle+1, upper);
            else
                return searchSortedItems(items, value, lower, middle-1);
        }
    
        // Simply calculates difference between the target value and each item in the array; O(n)
        private ArrayList computeDiffs(ArrayList items, int target) {
            ArrayList diffs = new ArrayList();
            for(int i = 0; i < items.size(); i++)
                diffs.add(target - items.get(i).getValue());
            return diffs;
        }
    
        // Sorts items using QuickSort algorithm in O(n Log n)
        private ArrayList quicksort(ArrayList items) {
            if (items.size() <= 1)
                return items;
            int pivot = items.size() / 2;
            ArrayList lesser = new ArrayList();
            ArrayList greater = new ArrayList();
            int sameAsPivot = 0;
            for (Item item : items) {
                if (item.getValue() > items.get(pivot).getValue())
                    greater.add(item);
                else if (item.getValue() < items.get(pivot).getValue())
                    lesser.add(item);
                else
                    sameAsPivot++;
            }
            lesser = quicksort(lesser);
            for (int i = 0; i < sameAsPivot; i++)
                lesser.add(items.get(pivot));
            greater = quicksort(greater);
            ArrayList sorted = new ArrayList();
            for (Item item : lesser)
                sorted.add(item);
            for (Item item: greater)
                sorted.add(item);
            return sorted;
        }
    
    
        public static void main(String[] args){
            int[] s = {150,24,79,50,88,345,3};
            int value = 200;
    
            NumbersFinder finder = new NumbersFinder();
            ArrayList numbers = finder.find(s, value);
    
            if(numbers != null){
                System.out.println("First Number Found = " + numbers.get(0).getValue() + " ; Index = " + + numbers.get(0).getIndex());
                System.out.println("Second Number Found = " + numbers.get(1).getValue() + " ; Index = " + + numbers.get(1).getIndex());
            }
            else{
                System.out.println("No such two numbers found in the array!");
            }
        }
    }
    

    Output:

    First Number Found = 50 ; Index = 3
    Second Number Found = 150 ; Index = 0
    

提交回复
热议问题