You are given an array of words where each word consists of lowercase English letters.
wordA is a predecessor of wordB if and only if we can insert exactly one letter anywhere in wordAwithout changing the order of the other characters to make it equal to wordB.
For example, "abc" is a predecessor of "abac", while "cba" is not a predecessor of "bcad".
A word chain is a sequence of words [word1, word2, ..., wordk] with k >= 1, where word1 is a predecessor of word2, word2 is a predecessor of word3, and so on. A single word is trivially a word chain with k == 1.
Return the length of the longest possible word chain with words chosen from the given list ofwords.
There are n gas stations along a circular route, where the amount of gas at the ith station is gas[i].
You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from the ith station to its next (i + 1)th station. You begin the journey with an empty tank at one of the gas stations.
Given two integer arrays gas and cost, return the starting gas station’s index if you can travel around the circuit once in the clockwise direction, otherwise return-1. If there exists a solution, it is guaranteed to be unique
Give a binary string s, return the number of non-empty substrings that have the same number of 0‘s and 1‘s, and all the 0‘s and all the 1‘s in these substrings are grouped consecutively.
Substrings that occur multiple times are counted the number of times they occur.
An array is said to be analogous to the secret array if all of the following conditions are true: • The length of the array is equal to the length of the secret array. • Each integer in the array lies in the interval [lowerBound, upperBound]. • The difference between each pair of consecutive integers of the array must be equal to the difference between the respective pair of consecutive integers in the secret array. In other words, let the secret array be [s[0], s[1],…, s[n-1]] and let the analogous array be [a[0], a[1],…, a[n-1]], then (a[i-1] - a[i]) must be equal to (s[i-1] - s[i]) for each i from 1 to n -1.
Given the value of integers lowerBound and upperBound, inclusive, and the array of differences between each pair of consecutive integers of the secret array, find the number of arrays that are analogous to the secret array. If there is no array analogous to the secret array, return 0.
Dynamic Programming is mainly an optimization over plain recursion. Wherever we see a recursive solution that has repeated calls for same inputs, we can optimize it using Dynamic Programming. The idea is to simply store the results of subproblems, so that we do not have to re-compute them when needed later.
int i = Integer.parseInt("000015640", 10); // 15640
Default initialization of an array in Java
Everything in a Java program not explicitly set to something by the programmer, is initialized to a zero value.
For references (anything that holds an object) that is null.
For int/short/byte/long that is a 0.
For float/double that is a 0.0
For booleans that is a false.
For char that is the null character '\u0000' (whose decimal equivalent is 0).
Initialize the capacity of a List
1
List<Integer> list = new ArrayList<>(10);
In this line of code, we initialize an array list with initial capacity of 10. Note that 10 is its capacity, not its size. So we still need to add elements one by one to this list. Assessing directly without adding any elements, such as directly calling list.get(1), will cause out-of-bound exceptions.
Reverse a List
1
Collections.reverse(list);
Create a List from an array
Take the return of Array.asList() as the parameter of ArrayList constructor.
1 2
int[] array = newint[10]; ArrayList<Integer> arraylIST = new ArrayList<>(Arrays.asList(array));
The point is that isLetter() will return false given a letter number. For example, roman numeral five (the letter looks like “V”). Certainly, for the English language, the distinction makes no difference.
Use Deque over Stack for LIFO stacks
We should use Deque rather than Stack for LIFO stacks.
1 2
Deque<Integer> dstack = new ArrayDeque<>(); Stack<Integer> sstack = new Stack<>(); // not recommended
There are many reasons to prefer Deque:
Deque is an interface but Stack is a class. So using Deque brings us more flexibility for future extension.
Stack is synchronized but Deque is not thread-safe. In the case of no need to ensure thread safety, Deque is more efficient.
Deque iterates elements from top to bottom. Stack iterates elements from bottom to top.
Most important: with Stack, we can access/insert/remove arbitrary elements in the LIFO stack by indexes, stack.get(index); stack.add(index, e); stack.remove(index), which breaks the LIFO rule. Although Deque does not absolutely obey the LIFO rule, it can only access/insert/remove the first/last element in the LIFO stack.
Print multi-dimensional arrays
1 2
System.out.println(Arrays.toString(arr)); // print a 1D array System.out.println(Arrays.deepToString(marr)); // print a multi-dimensional array
StringBuilder builder1 = new StringBuilder("abcdefg"); // if we want to delete c and add it back builder1.deleteCharAt(2); // "abdefg" builder1.insert(2, 'c'); // "abcdefg"
toCharArray() and getBytes()
toCharArray() is better if we are not dealing with characters outside of the Unicode BMP, which are encoded as two surrogate characters. getBytes() needs to specify encoding, which is prone to mistakes. Also, toCharArray() is faster because for Java 7 and newer, a String object contains a char array internally. toCharArray() just need to complete a copy operation.
Integer object comparison
For two Integer objects, == compares their references while < and > compare their values. To examinate whether they have the same value, we should use equals() or unbox them by intValue().
And, it is safe to use comparison operators (==, <, >) for comparing values between an int and an Integer object.
s.indexOf(pattern, fromIndex) returns the first index of given pattern from fromIndex (inclusive). If such pattern does not exist, it returns -1.
abstract keyword
If a class is declared abstract, it means that this class may be partially implementd. Thus, Java does not allow us to instantiate an abstract class. An abstract class can implement its constructor, functions (abstract or non-abstract) and have its variables.
An abstract function cannot have body. Any classes that declare any abstract functions must also be declared abstract. Any non-abstract classes that inherit abstract functions must implement all of them.
// the non-abstract subclass of an abstract class must implement all inherited abstract functions @Override publicvoidprintWorld(){ System.out.println("world"); } }
publicstaticvoidmain(String[] args){ // cannot instantiate an abstract class // Node n = new Node(); Node n = new ANode(1, "node1"); n.printHello(); n.printWorld(); }
Immutable objects
String and all primitive wrapper classes (Integer, Double, Long, Character, etc.) are immutable.
Inner class and nested class
An instance of inner class can exist only within an instance of its outerClass. The instance of the inner class has direct access to the methods and fields of its outer instance. A nested class can access all static resources of its outer class.
The difference between inner class and nested class is straightforward. Inner class has non-static features. Nested class has static features.
publicstaticvoidmain(String[] args){ // an instance of InnerClass can exist only within an instance of OuterClass // the instance of the inner class has direct access to the methods and fields of its outer instance TestInnerNested test = new TestInnerNested(); TestInnerNested.InnerClass inner = test.new InnerClass(); inner.print();
// a nest class can access all static resources of its outer class TestInnerNested.NestedClass nested = new TestInnerNested.NestedClass(); nested.print(); } }
Round a float number to n decimal places
Use DecimalFormat.
1 2 3
DecimalFormat df = new DecimalFormat("#.####"); df.setRoundingMode(RoundingMode.CEILING); System.out.println(df.format(15640.123456)); // 15640.1235
Traverse key-value pairs in a map
Use nested class Map.Entry<>.
1 2 3 4 5
Map<Integer, String> map = new HashMap<>(); for (Map.Entry<Integer, String> entry : map.entrySet()) { int key = entry.getKey(); String value = entry.getValue(); }
assert keyword
Do Not use assert in test. They can be activated at run-time by way of the -ea option on the java command, but are not turned on by default.
Split a string into at most 2 pieces
1
String[] arr = str.split(" ", 2);
Difference between Exception and RuntimeException
Any exception that derives from Exception is a checked exception. If a function throws an Exception in its body, it should also declare this behavior in this function declaration. Whereas a class that derives from RuntimeException is un-checked. RuntimeExceptions do not need to be explicitly handled by the calling code.
Generally RuntimeExceptions are exceptions that can be prevented programmatically.
floorEntry() and lowerEntry() of TreeMap
floorEntry(key) gets the entry corresponding to the specified key; if no such entry exists, returns the entry for the greatest key less than the specified key; if no such entry exists, returns null.
lowerEntry(key) returns the entry for the greatest key less than the specified key; if no such entry exists (i.e., the least key in the Tree is greater than the specified key), returns null.
Using a custom class as a key
To use a custom class as a key in Java Map, the custom class must define its equals and hashCode methods. Though Java provides an implicit implementation of these two methods for every class, the default implementation may lead to unexpected behaviors of Map (such as failing to find an existing key when inquiring with a new object with the same fields).
In C, integer division will truncate the result to zero, regardless of whether the result is positive or negative.
printf Conversion Specification %f
For example, %6.4f means printf should print the value as floating point, at least 6 characters wide (it means the total width) and 4 after the decimal point.