public static void spiralOrderPrint(int[][] matrix) { int tR = 0; int tC = 0; int dR = matrix.length - 1; int dC = matrix[0].length - 1; while (tR <= dR && tC <= dC) { printEdge(matrix, tR++, tC++, dR--, dC--); } }
public static void printEdge(int[][] m, int tR, int tC, int dR, int dC) { if (tR == dR) { for (int i = tC; i <= dC; i++) { System.out.print(m[tR][i] + " "); } } else if (tC == dC) { for (int i = tR; i <= dR; i++) { System.out.print(m[i][tC] + " "); } } else { int curC = tC; int curR = tR; while (curC != dC) { System.out.print(m[tR][curC] + " "); curC++; } while (curR != dR) { System.out.print(m[curR][dC] + " "); curR++; } while (curC != tC) { System.out.print(m[dR][curC] + " "); curC--; } while (curR != tR) { System.out.print(m[curR][tC] + " "); curR--; } } }
public static void printMatrixZigZag(int[][] matrix) { int tR = 0; int tC = 0; int dR = 0; int dC = 0; int endR = matrix.length - 1; int endC = matrix[0].length - 1; boolean fromUp = false; while (tR != endR + 1) { printLevel(matrix, tR, tC, dR, dC, fromUp); tR = tC == endC ? tR + 1 : tR; tC = tC == endC ? tC : tC + 1; dC = dR == endR ? dC + 1 : dC; dR = dR == endR ? dR : dR + 1; fromUp = !fromUp; } System.out.println(); }
public static void printLevel(int[][] m, int tR, int tC, int dR, int dC, boolean f) { if (f) { while (tR != dR + 1) { System.out.print(m[tR++][tC--] + " "); } } else { while (dR != tR - 1) { System.out.print(m[dR--][dC++] + " "); } } }
// O(N*logK) public static int[] getMinKNumsByHeap(int[] arr, int k) { if (k < 1 || k > arr.length) { return arr; } int[] kHeap = new int[k]; for (int i = 0; i != k; i++) { heapInsert(kHeap, arr[i], i); } for (int i = k; i != arr.length; i++) { if (arr[i] < kHeap[0]) { kHeap[0] = arr[i]; heapify(kHeap, 0, k); } } return kHeap; }
public static void heapInsert(int[] arr, int value, int index) { arr[index] = value; while (index != 0) { int parent = (index - 1) / 2; if (arr[parent] < arr[index]) { swap(arr, parent, index); index = parent; } else { break; } } }
public static void heapify(int[] arr, int index, int heapSize) { int left = index * 2 + 1; int right = index * 2 + 2; int largest = index; while (left < heapSize) { if (arr[left] > arr[index]) { largest = left; } if (right < heapSize && arr[right] > arr[largest]) { largest = right; } if (largest != index) { swap(arr, largest, index); } else { break; } index = largest; left = index * 2 + 1; right = index * 2 + 2; } } public static void swap(int[] arr, int index1, int index2) { int tmp = arr[index1]; arr[index1] = arr[index2]; arr[index2] = tmp; }
if (k < 1 || k > arr.length) { return arr; } int minKth = getMinKthByBFPRT(arr, k); int[] res = new int[k]; int index = 0; for (int i = 0; i != arr.length; i++) { if (arr[i] < minKth) { res[index++] = arr[i]; } } for (; index != res.length; index++) { res[index] = minKth; } return res; }
public static int getMinKthByBFPRT(int[] arr, int K) { int[] copyArr = copyArray(arr); return select(copyArr, 0, copyArr.length - 1, K - 1); }
public static int[] copyArray(int[] arr) { int[] res = new int[arr.length]; for (int i = 0; i != res.length; i++) { res[i] = arr[i]; } return res; }
public static int select(int[] arr, int begin, int end, int i) { if (begin == end) { return arr[begin]; } int pivot = medianOfMedians(arr, begin, end); int[] pivotRange = partition(arr, begin, end, pivot); if (i >= pivotRange[0] && i <= pivotRange[1]) { return arr[i]; } else if (i < pivotRange[0]) { return select(arr, begin, pivotRange[0] - 1, i); } else { return select(arr, pivotRange[1] + 1, end, i); } }
public static int medianOfMedians(int[] arr, int begin, int end) { int num = end - begin + 1; int offset = num % 5 == 0 ? 0 : 1; int[] mArr = new int[num / 5 + offset]; for (int i = 0; i < mArr.length; i++) { int beginI = begin + i * 5; int endI = beginI + 4; mArr[i] = getMedian(arr, beginI, Math.min(end, endI)); } return select(mArr, 0, mArr.length - 1, mArr.length / 2); }
public static int[] partition(int[] arr, int begin, int end, int pivotValue) { int small = begin - 1; int cur = begin; int big = end + 1; while (cur != big) { if (arr[cur] < pivotValue) { swap(arr, ++small, cur++); } else if (arr[cur] > pivotValue) { swap(arr, cur, --big); } else { cur++; } } int[] range = new int[2]; range[0] = small + 1; range[1] = big - 1; return range; }
public static int getMedian(int[] arr, int begin, int end) { insertionSort(arr, begin, end); int sum = end + begin; int mid = (sum / 2) + (sum % 2); return arr[mid]; }
public static void insertionSort(int[] arr, int begin, int end) { for (int i = begin + 1; i != end + 1; i++) { for (int j = i; j != begin; j--) { if (arr[j - 1] > arr[j]) { swap(arr, j - 1, j); } else { break; } } } }
public static void swap(int[] arr, int index1, int index2) { int tmp = arr[index1]; arr[index1] = arr[index2]; arr[index2] = tmp; }
public static void printArray(int[] arr) { for (int i = 0; i != arr.length; i++) { System.out.print(arr[i] + " "); } System.out.println(); }
public static int getLIL1(int[] arr) { if (arr == null || arr.length == 0) { return 0; } int len = 0; for (int i = 0; i < arr.length; i++) { for (int j = i; j < arr.length; j++) { if (isIntegrated(arr, i, j)) { len = Math.max(len, j - i + 1); } } } return len; }
public static boolean isIntegrated(int[] arr, int left, int right) { int[] newArr = Arrays.copyOfRange(arr, left, right + 1); // O(N) Arrays.sort(newArr); // O(N*logN) for (int i = 1; i < newArr.length; i++) { if (newArr[i - 1] != newArr[i] - 1) { return false; } } return true; }
public static int getLIL2(int[] arr) { if (arr == null || arr.length == 0) { return 0; } int len = 0; int max = 0; int min = 0; HashSet<Integer> set = new HashSet<Integer>(); for (int i = 0; i < arr.length; i++) { max = Integer.MIN_VALUE; min = Integer.MAX_VALUE; for (int j = i; j < arr.length; j++) { if (set.contains(arr[j])) { break; } set.add(arr[j]); max = Math.max(max, arr[j]); min = Math.min(min, arr[j]); if (max - min == j - i) { len = Math.max(len, j - i + 1); } } set.clear(); } return len; }