Binary Search using Template 1
: The key thing to understand in this template is that - Template #1 is used to search for an element or condition which can be determined by accessing a single index in the array. The search condition can be determined without having to look at the neighboring elements. No post-processing required because at each step, you are checking to see if the element has been found. If you reach the end, then you know the element is not found. <= in the while loop, we have to change left and right accordingly. Contrast this with the way that we are doing the same thing in the
case of Template #3 code below.
Binary Search using Template 3
: This is used to search for an element or condition which requires accessing the current index and its immediate left and right neighbor's index in the array. Loop/Recursion ends when you have 2 elements left. Need to assess if the remaining elements meet the condition. Again, take note of the looping condition in the while loop. At the point of termination of the while loop,left + 1 == right. Also note that in this
version of Binary Search, left and right are set to mid. Compare the same with the Template #1 being used above.
length > 0. int[] would contain the default value of 0 for each element, float[] would contain default values of 0.0, and boolean[]
would contain default values of false. while condition that will be written will be while (leftIndex <= rightIndex) and not
while (leftIndex < rightIndex). Or alternatively you can just use while(writeIndex >= 0). equals and deepEquals on SO.
equals and Arrays.equals on SO.
Note that array1.equals(array2) is the same as array1 == array2, i.e. is it the same array. Arrays.equals(array1, array2)
compares the contents of the arrays. Note that Arrays.equals() does not work as expected for multidimensional arrays, it only compares items of the 1st
dimension for reference equality. That's why we have Arrays.deepEquals(Object[], Object[]). Arrays.deepEquals(Object[], Object[]) is a
recursive call. Two arrays are equal if they contain the same elements in the same order. Two arrays are also equal if both of them are null.
Objects.equals(arg1, arg2) internally simply calls arg1.equals(arg2) method of arg1 (the first argument passed into the
Objects.equals method). Keep that in mind when you see the behavior of equals and Objects.equals in the case of arrays. List, is a story of its own. Read here on
Baeldung.
Comparator here. Also keep in
mind everything we went over regarding removing/modifying elements in a list while iterating over the same list like we discussed over here. List does not allow inserting an element at any arbitrary index by using the add(int index, E element) method. If the List is
empty, you can use only 0 as the index to add the first element to the list. If you have five elements in a List, you must use indexes between 0 and 5 to
add a new element to the List. The index from 0 to 4 will insert an element between existing elements. The index of 5 will append the element to the end of
the List. This implies that a List must grow sequentially. You cannot have a sparse List such as a List with first
element and tenth element, leaving second to ninth elements non-populated. This is the reason that a List is also known as a sequence. subList method present in the List interface as well. Write about that.
Arrays.sort(arrayName). You can also pass in a custom Comparator as a second args to sort it by something other
than the natural order. Refer here.
HashSet is one implementation of the Set datastructure that
does not allow duplicated values. The HashMap is an implementation of the Map datastructure that stores elements in the form of
<key, value>. Strings as keys for your Set/Map, then the complexity of checking whether a String exists in the set/map or not
is going to be O(m), where m is the number of characters in the string. Explained on SO here. Once you add
a String object to a Set/Map, the hashCode of the string is stored/cached in that String object. Hence, later
on if you use the same instance of the string to check for something like contains, the Set/Map will not have to recalculate the
hash again, since it will just use the cached value instead giving you O(1) time complexity. But if you use a new string object that is logically equal to the
earlier string that you added, but is a completely new instance of String, the hash value of it will have to be calculated all over again giving you O(m)
once again. Set/Map implementations, we have the TreeSet and TreeMap implementations as well. The time
complexity of basic operations (add, remove, contains) is
O(logN) on a TreeSet.
The TreeMap provides guaranteed log(n) time cost for the containsKey,
get, put and remove operations.
Also read the Computational Complexity of TreeSet methods in
Java on SO. add, remove, contains, size, the TreeSet/TreeMap do the add,
remove, contains in O(logN). Also note that the HashMap has a containsKey and containsValue method. The
containsKey has a O(1) time, whereas the containsValue has O(n) time because containsKey()
is just a get() that throws away the retrieved value. ConcurrentModificationException.
Like we discussed here. add() method to check if the element being added to
the set already existed in the Set or not. Point being, you do not need to separately use contains to check.
Map represents a key-value pair as <key, value>. A <key, value> pair is also known as an entry in the map. The
key and the value must be reference types. You cannot use primitive types (int, double, etc.) for either keys or values in a map. Map. You can view all keys in a Map as a
Set, all values as a Collection, and all <key, value> pairs as a Set. Note that all keys and all
<key, value> pairs are always unique in a Map and that is the reason why you get their Set views. Since a Map may
contain duplicate values, you get a Collection view of its values. Map while iterating over the same Map using the
removeIf method here on this page. HashMap from multiple items, you can use the Map.of() method as mentioned in this SO answer. Note that this creates an ImmutableMap, and also you can only add a max of 10 entries to the map using
this method. Collection, like a List. Basically we are trying to store all the positions that a character appears in a String. Can be used as a general
template for these kinds of questions.
LinkedHashMap to store the order of iteration over the string (and then iterating over the map to get the required answer),
use the given string to iterate and get the values from the HashSet to see if the condition is satisfied.
int[] numbers = new int[size];. Or you do: int[] numbers = new int[]{1,2,3,4,5}; else condition, you are probably going to run into an infinite loop condition
where none of the else if clauses are true, and hence the loop end condition never gets changed. So this is a bad idea. You need a else block to
catch everything else.