Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions AlienDictionary.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@

// In this problem, we have to identify that if the claim that words are sorted in alien order is correct or not. If correct than return
// order string else return "" empty string. So here, we are first building the graph, when comparing two consecutive words at a time
// if two chars are different we get to know that first char comes before second char, so there is a relation, there is a dependency,
// therefore it is a graph problem. Keeping one map to store the dependancy(char and the list of char depending on the key char), and
// indegrees list, so we will decrement the indegree of the node by 1, if it has some dependancy. And all the independent nodes we put
// in the queue, we can start from any char that is independent(indegree as 0) so we put all in queue. Then we start the bfs, poll the
// current char, append to stringbuilder sb, and check for it's dependant nodes, reduce their indegree by 1, and if it becomes zero
// put them in the queue.

// Time Complexity : O(nk) n length of words array and k avg length of each word
// Space Complexity : O(nk) dependancy Hashmap
// Did this code successfully run on Leetcode : yes
// Any problem you faced while coding this : no
import java.util.*;

public class AlienDictionary {
int[] indegrees;
HashMap<Character, List<Character>> m;

public String alienOrder(String[] words) {
// Base case
if (words == null || words.length == 0) {
return "";
}
// indegrees array of length 26, each index represent a char (a-z)
indegrees = new int[26];
// Map for storing the char and list<char>
m = new HashMap<>();
// constructGraph method will fill this two data structures
constructGraph(words);
// Queue for bfs
Queue<Character> q = new java.util.LinkedList<>();
// Ans
StringBuilder sb = new StringBuilder();
// Iterate over the map and check if any key from map having indegree zero, put
// them in queue
for (Character key : m.keySet()) {
if (indegrees[key - 'a'] == 0) {
q.add(key);
}
}
// Start bfs
while (!q.isEmpty()) {
// poll the current
char curr = q.poll();
// append to sb
sb.append(curr);
// Get the list of all dependant nodes(chars)
List<Character> allChar = m.get(curr);
// if it is null, continue
if (allChar.size() == 0) {
continue;
}
// Else for each char, reduce their indegree by 1 and if it becomes 0, put the
// char in queue
for (char singleChar : allChar) {
indegrees[singleChar - 'a']--;
if (indegrees[singleChar - 'a'] == 0) {
q.add(singleChar);
}
}
}
// At last if the string size is not equal to the map size, means we have not
// got the correct order
if (sb.length() != m.size()) {
return "";
}
// Else return string
return sb.toString();
}

private void constructGraph(String[] words) {
// First go over each word, each char, put all the unique chars in map with
// empty list as value
for (int i = 0; i < words.length; i++) {
for (int j = 0; j < words[i].length(); j++) {
if (!m.containsKey(words[i].charAt(j))) {
m.put(words[i].charAt(j), new ArrayList<>());
}
}
}
// Go over each words
for (int i = 0; i < words.length - 1; i++) {
// Take two consecutive words at a time
String first = words[i];
String second = words[i + 1];
// Take their length
int m1 = first.length();
int n = second.length();
// If the first word startswith second, that means not sorted, so clear map and
// return
if (first.startsWith(second) && m1 > n) {
m.clear();
return;
}
// Else compare each char
for (int j = 0; j < n && j < m1; j++) {
char firstChar = first.charAt(j);
char secondChar = second.charAt(j);
// If different
if (firstChar != secondChar) {
// Increase the indegree of second char by 1
indegrees[secondChar - 'a']++;
// And add to the list in map
m.get(firstChar).add(secondChar);
}
}
}
}

public static void main(String[] args) {
String[] words = new String[] { "wrt", "wrf", "er", "ett", "rfttz" };
AlienDictionary a = new AlienDictionary();
System.out.println(a.alienOrder(words));
}
}
82 changes: 82 additions & 0 deletions FindACelebrity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// In this problem, simply traversing through the 2 by 2 matrix and maintainin a indegrees array. As we know that for a celeb since
// everyone knows celeb, the indegree value will be n-1, and since celeb doesnt know anyone the outdegree value will be 0. So in this
// indegree array if we find that i knows j, we decrement the indegree[i] by 1 indicating an outgoing edge, and increment the indegree[j]
// by 1, indicating an incoming edge. At end check if any index having n-1, that is our ans else -1.
// Time Complexity : O(n^2)
// Space Complexity : O(n)
// Did this code successfully run on Leetcode : yes
// Any problem you faced while coding this : no
public class FindACelebrity extends Relation {
public int findCeleb(int n) {
// Base case
if (n == 0) {
return -1;
}
// Indegree array
int[] indegree = new int[n];
// Loop through n*n
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
// Check for all the combinations except i==j
if (i != j) {
// Check if the i knows j
if (knows(i, j)) {
// Decrement
indegrees[i]--;
// Increment
indegrees[j]++;
}
}
}
}
// Check what contains the n-1 value, return that i
for (int i = 0; i < n; i++) {
if (indegrees[i] == n - 1) {
return i;
}
}
// Else -1
return -1;
}
}

// In this approach, we are making assumption that 0 is our celeb, than running
// a loop and checking if there is anyone to whom our
// current celeb (0) knows, if yes than making that person as the celeb, becoz 0
// is knowing someone so 0 cant be celeb. Now with this
// second celeb, we check if everyone knows him and he doenst know anyone, if
// any breach found, return -1, else return this celeb.

// Time Complexity : O(n)
// Space Complexity : O(1)
// Did this code successfully run on Leetcode : yes
// Any problem you faced while coding this : no
public class FindACelebrity extends Relation {
public int findCeleb(int n) {
// Base case
if (n == 0) {
return -1;
}
int celeb = 0;
// Loop over and check if the first assumed celeb is knowing anyone
for (int i = 0; i < n; i++) {
if (i != celeb) {
if (knows(celeb, i)) {
// Then 0 cannot be celeb, so change the celeb to the person whom 0 knows that
// is i
celeb = i;
}
}
}
// Now again loop over and check if this celeb knows anyone or anyone doesnt
// know this celeb, then return -1, else return this celeb
for (int i = 0; i < n; i++) {
if (i != celeb) {
if (knows(i, celeb) == 0 || knows(celeb, i) == 1) {
return -1;
}
}
}
return celeb;
}
}
64 changes: 64 additions & 0 deletions VerifyingAlienDictionary.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// In this problem, using hashmap to store the order string with it's index. Then going over the array and comparing each consecutive
// words, if there is any char that is not matching, checking its index value in map, if the first word char has lower index value
// than the second word char, than returning true, else false. Also if the chars match and first word has length greater than the second
// word, returning false.

// Time Complexity : O(nk) n length of words array and k avg length of each word
// Space Complexity : O(1)
// Did this code successfully run on Leetcode : yes
// Any problem you faced while coding this : no
class Solution {
HashMap<Character, Integer> map;

public boolean isAlienSorted(String[] words, String order) {
// Base case
if (words == null || words.length == 0) {
return true;
}
map = new HashMap<>();
// Loop and put the order string in the map
for (int i = 0; i < order.length(); i++) {
char c = order.charAt(i);
map.put(c, i);
}
// Now loop over all words
for (int i = 0; i < words.length - 1; i++) {
// Take two consecutive words at a time
String first = words[i];
String second = words[i + 1];
// Check if not ordered
if (isNotOrdered(first, second)) {
// Return false
return false;
}
}
// return true
return true;
}

private boolean isNotOrdered(String first, String second) {
// Take the length of two words
int m = first.length();
int n = second.length();
// Loop over each char
for (int i = 0; i < m && i < n; i++) {
// Take two chars
char firstChar = first.charAt(i);
char secondChar = second.charAt(i);
// Check if not equal
if (firstChar != secondChar) {
// Check their index position in map
if (map.get(firstChar) > map.get(secondChar)) {
// If first greater, means not sorted, so return true
return true;
} else {
// Else false
return false;
}
}
}
// If no chars mismatch and the length of the first is greater than second, not
// sorted, so return true else false
return (m > n);
}
}