Array Flashcards
Array, Even appears first time comp O(n), Space comp O(1)
public static void evenOdd(List A) { int nextEven = 0, nextOdd = A.size() - 1; while (nextEven < nextOdd) { if (A.get(nextEven) % 2 == 0) { nextEven++; } else { Collections.swap(A, nextEven, nextOdd–); } } }
Filling an array from 1. the front 2. the back is faster
- the back
Array, 1. delete en entry 2. overwrite an entry is better performance
- overwrite an entry deleting an entry requires moving all entries to its left
Integer encoded by an array 1. processing the digits from the back 2. processing the digits from the front of the array is better
- processing the digits from the back
DutchNational Flag algo Time Comp O(n) Space Comp O(1)
public static void dutchFlagPartition(int pivotIndex, List A) { Color pivot = A.get(pivotIndex); /** * Keep the following invariants during partitioning: * bottom group: A.subList(0, smaller). * middle group: A.subList(smaller, equal). * unclassified group: A.subList(equal, larger). * top group: A.subList(larger, A.size()). */ int smaller = 0, equal = 0, larger = A.size(); // Keep iterating as long as there is an unclassified element. while (equal < larger) { // A.get(equal) is the incoming unclassified element. if (A.get(equal).ordinal() < pivot.ordinal()) { Collections.swap(A, smaller++, equal++); } else if (A.get(equal).ordinal() == pivot.ordinal()) { ++equal; } else { // A.get(equal) > pivot. Collections.swap(A, equal, –larger); } } }
Increment an non-negative integer by one Time comp O(n)
public static List plusOne(List A) { int n = A.size() - 1; A.set(n, A.get(n) + 1); for (int i = n; i > 0 && A.get(i) == 10; –i) { A.set(i, 0); A.set(i - 1, A.get(i - 1) + 1); } if (A.get(0) == 10) { // There is a carry-out, so we need one more digit to store the result. // A slick way to do this is to append a 0 at the end of the array, // and update the first entry to 1. A.set(0, 1); A.add(0); } return A; }
Multiply Two Integer in the array Time O(nm)
public static List multiply(List num1, List num2) { final int sign = num1.get(0) < 0 ^ num2.get(0) < 0 ? -1 : 1; // MSB shows negative or positive num1.set(0, Math.abs(num1.get(0))); // remove the sign for now num2.set(0, Math.abs(num2.get(0)));// remove the sign for now List result = new ArrayList<>(Collections.nCopies(num1.size() + num2.size(), 0)); // result size will be equal to or more than num1 size + num2 size for (int i = num1.size() - 1; i >= 0; –i) { for (int j = num2.size() - 1; j >= 0; –j) { result.set(i + j + 1, result.get(i + j + 1) + num1.get(i) * num2.get(j)); result.set(i + j, result.get(i + j) + result.get(i + j + 1) / 10); result.set(i + j + 1, result.get(i + j + 1) % 10); } } // Remove the leading zeroes. int firstNotZero = 0; while (firstNotZero < result.size() && result.get(firstNotZero) == 0) { ++firstNotZero; } result = result.subList(firstNotZero, result.size()); if (result.isEmpty()) { return List.of(0); } result.set(0, result.get(0) * sign); return result; }
Advancing thru an array Time O(n) Space O(1)
public static boolean canReachEnd(List maxAdvanceSteps) { int furthestReachSoFar = 0, lastIndex = maxAdvanceSteps.size() - 1; for (int i = 0; i <= furthestReachSoFar && furthestReachSoFar < lastIndex; ++i) { furthestReachSoFar = Math.max(furthestReachSoFar, i + maxAdvanceSteps.get(i)); } return furthestReachSoFar >= lastIndex; }
Delete Duplicates from a sorted array Time O(n) and Space O(1)
// Returns the number of valid entries after deletion. public static int deleteDuplicates(List A) { if (A.isEmpty()) { return 0; } int writeIndex = 1; for (int i = 1; i < A.size(); ++i) { if (!A.get(writeIndex - 1).equals(A.get(i))) { A.set(writeIndex++, A.get(i)); } } return writeIndex; }
Buy and sell stock compute max profit in buying and selling one share of the stock Time O(n) Space O(1)
public static double computeMaxProfit(List prices) { double minPrice = Double.MAX_VALUE, maxProfit = 0.0; for (Double price : prices) { maxProfit = Math.max(maxProfit, price - minPrice); minPrice = Math.min(minPrice, price); } return maxProfit; }
Buy and sell stock twice compute max profit in buying and selling stock twice Time O(n) Space O(1)
private static double buyAndSellStockTwiceConstantSpace(List prices) { List minPrices = List.of(Double.MAX_VALUE, Double.MAX_VALUE), maxProfits = List.of(0.0, 0.0); for (Double price : prices) { for (int i = 1; i >= 0; –i) { maxProfits.set(i, Math.max(maxProfits.get(i), price - minPrices.get(i))); minPrices.set( i, Math.min(minPrices.get(i), price - (i - 1 >= 0 ? maxProfits.get(i - 1) : 0.0))); } } return maxProfits.get(1); }
rearrange array’s element in an alternation time O(n)
public static void rearrange(List A) { for (int i = 1; i < A.size(); ++i) { if (((i % 2) == 0 && A.get(i - 1) < A.get(i)) || ((i % 2) != 0 && A.get(i - 1) > A.get(i))) { Collections.swap(A, i - 1, i); } } }
generate prime Space O(n) Time O(n^(3/2))
// Given n, return all primes up to and including n. public static List generatePrimes(int n) { if (n < 2) { return Collections.emptyList(); } final int size = (int)Math.floor(0.5 * (n - 3)) + 1; List primes = new ArrayList<>(); primes.add(2); // isPrime.get(i) represents whether (2i + 3) is prime or not. // For example, isPrime.get(0) represents 3 is prime or not, // isPrime.get(1) represents 5, isPrime.get(2) represents 7, etc. // Initially, set each to true. Then use sieving to eliminate nonprimes. List isPrime = new ArrayList<>(Collections.nCopies(size, true)); for (long i = 0; i < size; ++i) { if (isPrime.get((int)i)) { int p = (((int)i * 2) + 3); primes.add(p); // Sieving from p^2, whose value is (4i^2 + 12i + 9). The index of this // value in isPrime is (2i^2 + 6i + 3) because isPrime.get(i) represents // 2i + 3. // // Note that we need to use long type for j because p^2 might overflow. for (long j = ((i * i) * 2) + 6 * i + 3; j < size; j += p) { isPrime.set((int)j, false); } } } return primes; }
Given an array A of n elements and a permutation P, apply P to A Time O(n) Space O(n)
public static void applyPermutation(List perm, List A) { for (int i = 0; i < A.size(); ++i) { while (perm.get(i) != i) { Collections.swap(A, i, perm.get(i)); Collections.swap(perm, i, perm.get(i)); } } }
Write s program that takes as input an array of integers, and returns the next array under lexicographical ordering, from the set of all arrays that are permutations of the input array. Time O(n) Space O(1)
public static List nextPermutation(List perm) { // Find the first entry from the right that is smaller than the entry // immediately after it. int inversionPoint = perm.size() - 2; while (inversionPoint >= 0 && perm.get(inversionPoint) >= perm.get(inversionPoint + 1)) { –inversionPoint; } if (inversionPoint == -1) { return Collections.emptyList(); // perm is the last permutation. } // Swap the smallest entry after index inversionPoint that is greater than // perm.get(inversionPoint). Since entries in perm are decreasing after // inversionPoint, if we search in reverse order, the first entry that is // greater than perm.get(inversionPoint) is the entry to swap with. for (int i = perm.size() - 1; i > inversionPoint; –i) { if (perm.get(i) > perm.get(inversionPoint)) { Collections.swap(perm, inversionPoint, i); break; } } // Entries in perm must appear in decreasing order after inversionPoint, so // we simply reverse these entries to get the smallest dictionary order. Collections.reverse(perm.subList(inversionPoint + 1, perm.size())); return perm; }