String[] countWords(String sentence, int returnWordCount) {
		
		// check input parameter
		if (sentence == null || sentence.isEmpty()) {
			System.out.println("Sentence not defined");
			return null;
		}
		
		// check input parameter
		if (returnWordCount <= 0) {
			System.out.println("Return Words must be greater than zero");
			return null;
		}

		// store count for each word discovered, indexed by word
		HashMap<String, Integer> wordFreq = new HashMap<>();
		
		// remove all characters that are not spaces, letters, or digits
		final String regex = "[^a-zA-Z\\d\\ ]";
		sentence = sentence.replaceAll(regex, "");
		
		// parse string by space
		StringTokenizer token = new StringTokenizer(sentence); 
		
		// count the word frequency in the sentence.  This operation is O(n)
		while (token.hasMoreElements()) {
			String word = (String) token.nextElement();
			
			if (wordFreq.containsKey(word)) {
				// existing word found. Increment word count
				Integer count = wordFreq.get(word) + 1;
				wordFreq.put(word, count);
				
			} else {
				// new word found, initial count is 1
				wordFreq.put(word, 1);
			}
		}
		
		// Construct a heap from the hashmap sorted so that most frequent words are at the nodes
		// are at the head of the queue
		ReverseWordComparitor rComparator = new ReverseWordComparitor();
		PriorityQueue<Node> sortedWords = new PriorityQueue<>(wordFreq.size(), rComparator);

		// Add items to the heap.  Insertion takes O(n)
		for (Map.Entry<String, Integer> entry : wordFreq.entrySet()) {
			sortedWords.add(new Node(entry.getKey(), entry.getValue()));
		}
		
		// check if return size is valid for number of words.   If number of words less than return size,
		// adjust return size.
		if (returnWordCount > sortedWords.size()) {
			returnWordCount = sortedWords.size();
			System.out.println("Return words size " + returnWordCount + " too high. Setting to " + sortedWords.size());
		}
		
		// pop off the top number of entries until returnWordCount satisfied
		String[] returnList = new String[returnWordCount];
		
		// add the words to the return list. Worst case is O(n) where returnWordCount equals n.
		for (int i = 0; i < returnList.length; i++) {
			returnList[i] = sortedWords.remove().word;
		}
		
		return returnList;
	}