Leetcode Blog Post Algorithms



package leetcode.blog;

import java.util.ArrayList;
import java.util.Arrays;

public class LeetcodeBlog {
	// Q1 Find Intersection of two Sorted Arrays
	// if either A or B 's length is too big, try to use Binary Search should be
	// a good idea, which is O(mlgn)
	// this method is O(m + n)
	public static ArrayList<Integer> findIntersection(int[] A, int[] B) {
		ArrayList<Integer> res = new ArrayList<Integer>();
		if (A.length == 0 || B.length == 0)
			return res;
		for (int i = 0, j = 0; i < A.length && j < B.length;) {
			if (A[i] == B[j]) {
				res.add(A[i]);
				i++;
				j++;
			} else if (A[i] < B[j])
				i++;
			else
				j++;
		}
		return res;
	}

	// Q2 Reverse Linked List both Iteratively and Recursively
	public static LinkedListNode reverseLinkedListIteratively(
			LinkedListNode head) {
		if (head == null)
			return head;
		LinkedListNode res = new LinkedListNode(0);
		LinkedListNode next;
		while (head != null) {
			next = head.next;
			head.next = res.next;
			res.next = head;
			head = next;
		}
		return res.next;
	}

	public static LinkedListNode reverseLinkedListRecursively(
			LinkedListNode head) {
		if (head == null)
			return head;
		if (head.next == null)
			return head;
		LinkedListNode newHead = reverseLinkedListRecursively(head.next);
		head.next.next = head;
		head.next = null;
		return newHead;
	}

	// Q3 Determine if a point is inside a rectangle/irregular polygon
	// Rectangle ABCD and Point P
	// 1. Calculate the sum of areas of all triangles. ABP, BCP, CDP, DAP.
	// if the sum is larger than the area of the rectangle, P is outside the
	// rectangle
	// if the sum is smaller than the area of the rectangle, P is inside the
	// rectangle
	// if equal, it is on one side line.
	// 2. Calculate the perpendicular distances of P from all the 4 lines

	// Q4 Rotating an array in place
	public static void rotateArray(int[] array, int k) {
		reverse(array, 0, array.length - 1);
		reverse(array, 0, k - 1);
		reverse(array, k, array.length - 1);
	}

	public static void reverse(int[] array, int left, int right) {
		int temp;
		while (left < right) {
			temp = array[left];
			array[left] = array[right];
			array[right] = temp;
			left++;
			right--;
		}
	}

	// Q5 Multiplication of Numbers
	/*
	 * There is an array A[N] of N numbers. You have to compose an array
	 * Output[N] such that Output[i] will be equal to multiplication of all the
	 * elements of A[N] except A[i]. Solve it without division operator and in
	 * O(n). For example Output[0] will be multiplication of A[1] to A[N-1] and
	 * Output[1] will be multiplication of A[0] and from A[2] to A[N-1].
	 * Example: A: {4, 3, 2, 1, 2} OUTPUT: {12, 16, 24, 48, 24}
	 */
	public static int[] multiplyNumbers(int[] num) {
		int n = num.length;
		int[] output = new int[n];
		if (n == 0)
			return output;
		Arrays.fill(output, 1);
		int left = 1, right = 1;
		for (int i = 0; i < n; i++) {
			output[i] *= left;
			output[n - i - 1] *= right;
			left *= num[i];
			right *= num[n - 1 - i];
		}
		return output;
	}

	/*
	 * Q6 Generate a prime list from 0 up to n, using The Sieve of Erantosthenes
	 * param n The upper bound of the prime list (including n) param prime[] An
	 * array of truth value whether a number is prime
	 */
	public static ArrayList<Integer> generatePrime(int n) {
		boolean[] prime = new boolean[n + 1];
		if (n < 2)
			return new ArrayList<Integer>();
		Arrays.fill(prime, true);
		prime[0] = false;
		prime[1] = false;
		int limit = (int) Math.sqrt((double) n);
		for (int i = 2; i <= limit; i++) {
			if (prime[i]) {
				for (int j = i * i; j <= n; j += i)
					prime[j] = false;
			}
		}
		ArrayList<Integer> res = new ArrayList<Integer>();
		for (int i = 0; i <= n; i++)
			if (prime[i])
				res.add(i);
		return res;
	}

	/*
	 * Q7 Given a string of lowercase characters, reorder them such that the
	 * same characters are at least distance d from each other. Input: { a, b, b
	 * }, distance = 2 Output: { b, a, b }
	 */
	public static int findMax(int freqeuncy[], boolean excep[]) {
		int max_i = -1;
		int max = -1;
		for (int i = 0; i < 26; i++) {
			if (!excep[i] && freqeuncy[i] > 0 && freqeuncy[i] > max) {
				max = freqeuncy[i];
				max_i = i;
			}
		}
		return max_i;
	}

	public static char[] keepDis(char[] str, int d) {
		int n = str.length;
		char[] res = new char[n];
		int freqeuncy[] = new int[26];
		for (int i = 0; i < n; i++)
			freqeuncy[str[i] - 'a']++;
		int distance[] = new int[26];
		boolean excep[] = new boolean[26];
		for (int i = 0; i < n; i++) {
			Arrays.fill(excep, false);
			boolean done = false;
			while (!done) {
				int j = findMax(freqeuncy, excep);
				if (j == -1) {
					System.out.println("Invalid inputs.");
					return res;
				}
				excep[j] = true;
				if (distance[j] <= 0) {
					res[i] = (char) (j + 'a');
					freqeuncy[j]--;
					distance[j] = d;
					done = true;
				}
			}
			for (int k = 0; k < 26; k++)
				distance[k]--;
		}
		return res;
	}

	/*
	 * Q8 Check whether an integer is a power of two.
	 */
	boolean mystery(int x) {// bug is when x == 0
		return (x & (x - 1)) == 0;
	}

	boolean mysteryZero(int x) {
		return x != 0 && (x & (x - 1)) == 0;
	}

	/*
	 * Q9 Number of 1 bits
	 */
	public static int countOneBitsCommon(int x) {
		int counter = 0;
		while ((x & 0x1) != 0) {
			counter++;
			x = x >> 1;
		}
		return counter;
	}

	public static int countOneBits(int x) {
		int counter = 0;
		while (x != 0) {
			counter++;
			x = x & (x - 1);
		}
		return counter;
	}

	/*
	 * Q10
	 * Pre-order BST constructor
	 */
	public static int index = 0;
	public static TreeNode preorderConstructBST(int[] array, int min, int max){
		if(index < array.length && array[index] < max && array[index] > min){
			TreeNode root = new TreeNode(array[index++]);
			root.left = preorderConstructBST(array, min, root.val);
			root.right = preorderConstructBST(array, root.val, max);
			return root;
		}
		return null;
	}
	/*
	 * Q11
	 * Deserialize a Binary Tree (any tree has an identical binary tree representation)
	 */
	public static void serialize(TreeNode root, ArrayList<Integer> array){
		if(root == null)
			array.add(-1);
		else{
			array.add(root.val);
			serialize(root.left, array);
			serialize(root.right, array);
		}
	}
	/*
	 * Q12
	 * Excel sheet row numbers
	 */
	// start from 0
	public static String convert(int row){
		StringBuffer sb = new StringBuffer("");
		sb.append((char)('a' + row % 26));
		row /= 26;
		while(row != 0){
			int index = (row - 1) % 26;
			row = (row - 1) / 26;
			sb.insert(0, (char)(index + 'a'));
		}
		return sb.toString();
	}
	// start from 1
	public static String convert2(int row){
		StringBuffer sb = new StringBuffer("");
		while(row != 0){
			int index = row % 26;
			row /= 26;
			sb.insert(0, (char)(index + 'a' - 1));
		}
		return sb.toString();
	}
	// Q13 Search Young Tableau
	// O(n)
	public static boolean stepwise(int[][] table, int target){
		if(table.length == 0)
			return false;
		if(table[0].length == 0)
			return false;
		int row = table.length;
		int col = table[0].length;
		if(target < table[0][0] || target > table[row - 1][col - 1])
			return false;
		for(int i = 0, j = 0; i < row && j >= 0;){
			if(table[i][j] == target)
				return true;
			else if(table[i][j] > target)
				j--;
			else
				i++;
		}
		return false;
	}
	// O(n^1.58)
	// row number ranges from top to bottom, column number ranges from left to right
	public static boolean quadPartition(int[][] table, int target, int left, int top, int right, int bottom){
		if(left > right || top > bottom)
			return false;
		if(target < table[top][left] || target > table[bottom][right])
			return false;
		int col = (right + left) / 2;
		int row = (top + bottom) / 2;
		if(table[row][col] == target)
			return true;
		else if (left == right && top == bottom)
			return false;
		if(table[row][col] > target){// upper left || upper right || bottom left
			return quadPartition(table, target, left, top, col, row) ||
					quadPartition(table, target, col + 1, top, right, row) ||
					quadPartition(table, target, left, row + 1, col, bottom);
		} else { // upper right || bottom right || bottom left
			return quadPartition(table, target, col + 1, top, right, bottom) ||
					quadPartition(table, target, col + 1, row + 1, right, bottom) ||
					quadPartition(table, target, left, row + 1, col, bottom);
		}
	}
	// do search on mid column, and then search on upper right side and bottom left side
	// if two sub-matrices are equal sizes, then O(n)
	public static boolean binaryPartition(int[][] table, int target, int left, int top, int right, int bottom){
		if(left > right || top > bottom)
			return false;
		if(target < table[top][left] || target > table[bottom][right])
			return false;
		int mid = (left + right) / 2;
		int row = top;
		// Could use binary search here which reduce complexity to O(lgn * lgn)
		while(row <= bottom && table[row][mid] <= target){
			if(table[row][mid] == target)
				return true;
			row++;
		}
		// upper right || bottom left
		return binaryPartition(table, target, mid + 1, top, top, row - 1) ||
				binaryPartition(table, target, left, row, mid - 1, bottom);
	}
	// Q14 Print boundary edges of a binary tree
	public static ArrayList<Integer> printEdges(TreeNode root){
		ArrayList<Integer> res = new ArrayList<Integer>();
		if(root == null)
			return res;
		res.add(root.val);
		printLeftBottomEdges(root.left, true, res);
		printBottomRightEdges(root.right, true, res);
		return res;
	}
	public static void printLeftBottomEdges(TreeNode root, boolean print, ArrayList<Integer> res){
		if(root == null)
			return;
		if(print || (root.left == null && root.right == null))
			res.add(root.val);
		printLeftBottomEdges(root.left, print, res);
		printLeftBottomEdges(root.right, print && root.left == null ? true : false, res);
	}
	public static void printBottomRightEdges(TreeNode root, boolean print, ArrayList<Integer> res){
		if(root == null)
			return;
		printBottomRightEdges(root.left, print && root.right == null ? true : false, res);
		printBottomRightEdges(root.right, print, res);
		if(print || (root.left == null && root.right == null))
			res.add(root.val);
	}
	// Q15
	public static String Q15replace(String str, String pattern){
		if(str == null || pattern == null || pattern.length() > str.length())
			return str;
		StringBuilder sb = new StringBuilder("");
		int lastStart = 0, curStart = 0, curEnd = 0;
		while(curStart != str.length()){
			if(curStart + pattern.length() <= str.length() && match(str.substring(curStart, curStart + pattern.length()), pattern)){
				sb.append(str.substring(lastStart, curStart));
				if(sb.length() == 0 || sb.charAt(sb.length() - 1) != 'X')
					sb.append('X');
				curEnd = curStart + pattern.length();
				lastStart = curEnd;
				curStart = curEnd;
			} else {
				curStart++;
			}
		}
		if(curEnd != str.length())
			sb.append(str.substring(lastStart, str.length()));
		return sb.toString();
	}
	public static boolean match(String s, String p){
		int i = 0;
		while(i != s.length() && i != p.length()){
			if(s.charAt(i) != p.charAt(i))
				return false;
			i++;
		}
		if(i == p.length())
			return true;
		return false;
	}
	// Q16 from random7() to random10()
	// E(# of call random7) is 2.45. We throw away idx from 41 to 49
	public static int random10(){
		int row, col, idx;
		do {
			row = random7();
			col = random7();
			idx = col + (row - 1) * 7;
		} while(idx > 40);
		return 1 + (idx - 1) % 10;
	}
	public static int random7(){
		return (int)(Math.random() * 7 + 1);
	}
	// E(# of call random7) is 2.21. We utilize integers from 41 to 49, and integers from 61 to 63
	public static int random10_better(){
		int row, col, idx;
		while(true){
			row = random7();
			col = random7();
			idx = col + (row - 1) * 7;
			if(idx <= 40)
				return 1 + (idx - 1) % 10;
			row = row - 40;
			col = random7();
			idx = col + (row - 1) * 7;
			if(idx <= 60)
				return 1 + (idx - 1) % 10;
			row = row - 60;
			col = random7();
			idx = col + (row - 1) * 7;
			if(idx <= 20)
				return 1 + (idx - 1) % 10;
		}
	}
	//Q 17
	// Largest Subtree which is a BST
	static TreeNode largestSubRoot = null;
	static int min, max, maxNodes;
	// min and max are for subtree, so the root.val should be outside of [min, max]
	public static TreeNode largestSubtree(TreeNode root){
		findLargestSubtree(root);
		return largestSubRoot;
	}
	public static int findLargestSubtree(TreeNode root){
		if(root == null)
			return 0;
		boolean isBST = true;
		int leftNodes = findLargestSubtree(root.left);
		int curMin = (leftNodes == 0) ? root.val : min;
		if(leftNodes == -1 || (leftNodes != 0 && root.val <= max)) // root.val in the range of subtree values, thus not BST
			isBST = false;
		int rightNodes = findLargestSubtree(root.right);
		int curMax = (rightNodes == 0) ? root.val : max;
		if(rightNodes == -1 || (rightNodes != 0 && root.val >= min)) // root.val in the range of subtree values, thus not BST
			isBST = false;
		if(isBST){
			min = curMin;
			max = curMax;
			int totalNodes = leftNodes + rightNodes + 1;
			if(totalNodes > maxNodes){
				maxNodes = totalNodes;
				largestSubRoot = root;
			}
			return totalNodes;
		} else
			return -1;
	}
	// Q18
	static int maxNodesBST;
	static TreeNode largestBST;
	static TreeNode child;
	public int findLargestBST(TreeNode root, int min, int max){
		if(root == null)
			return 0;
		if(min < root.val && root.val < max){
			int leftNodes = findLargestBST(root.left, min, root.val);
			TreeNode leftChild = (leftNodes == 0) ? null : child;
			int rightNodes = findLargestBST(root.right, root.val, max);
			TreeNode rightChild = (rightNodes == 0) ? null : child;
			TreeNode parent = new TreeNode(root.val);
			parent.left = leftChild;
			parent.right = rightChild;
			child = parent;
			int totalNodes = leftNodes + rightNodes + 1;
			if(totalNodes > maxNodes){
				maxNodes = totalNodes;
				largestBST = parent;
			}
			return totalNodes;
		} else {
			findLargestBST(root, Integer.MIN_VALUE, Integer.MAX_VALUE);
			return 0;
		}
	}
	
	// Q19
	public TreeNode constructFromList(LinkedListNode head, int start, int end){
		if(start > end)
			return null;
		int mid = (start + end) / 2;
		TreeNode left = constructFromList(head, start, mid - 1);
		TreeNode parent = new TreeNode(head.value);
		parent.left = left;
		head = head.next;
		parent.right = constructFromList(head, mid + 1, end);
		return parent;
	}
	
	public static void main(String[] args) {
		// Q1
		int[] A = { 1, 2, 3, 4, 5, 6, 7 };
		int[] B = { 4, 5, 6, 7, 8, 9, 10, 11, 12 };
		ArrayList<Integer> res = findIntersection(A, B);
		for (int i = 0; i < res.size(); i++)
			System.out.print(res.get(i) + " ");
		System.out.println();
		// Q2
		LinkedListNode head = new LinkedListNode(1);
		head.next = new LinkedListNode(2);
		head.next.next = new LinkedListNode(3);
		head = reverseLinkedListIteratively(head);
		while (head != null) {
			System.out.print(head.value + " ");
			head = head.next;
		}
		System.out.println();
		// Q3
		head = new LinkedListNode(1);
		head.next = new LinkedListNode(2);
		head.next.next = new LinkedListNode(3);
		head = reverseLinkedListRecursively(head);
		while (head != null) {
			System.out.print(head.value + " ");
			head = head.next;
		}
		System.out.println();
		// Q4
		rotateArray(A, 3);
		for (int i = 0; i < A.length; i++)
			System.out.print(A[i] + " ");
		System.out.println();
		// Q5
		A = new int[] { 4, 3, 2, 1, 2 };
		A = multiplyNumbers(A);
		for (int i = 0; i < A.length; i++)
			System.out.print(A[i] + " ");
		System.out.println();
		// Q6
		ArrayList<Integer> primes = generatePrime(103);
		for (int i = 0; i < primes.size(); i++)
			System.out.print(primes.get(i) + " ");
		System.out.println();
		// Q7
		char[] charList = keepDis(new char[] { 'a', 'b', 'b' }, 2);
		for (int i = 0; i < charList.length; i++)
			System.out.print(charList[i] + " ");
		System.out.println();
		// Q9
		System.out.println("Count 1 bits: " + countOneBitsCommon(7));
		System.out.println("Count 1 bits: " + countOneBits(7));
		// Q10
		int[] array = new int[]{7, 3, 1, 0, 2, 4, 6, 8};
		TreeNode  root = preorderConstructBST(array, Integer.MIN_VALUE, Integer.MAX_VALUE);
		System.out.println();
		//Q11
		ArrayList<Integer> selist = new ArrayList<Integer>();
		serialize(root, selist);
		for(int i = 0; i < selist.size(); i++){
			System.out.print(selist.get(i) + " ");
		}
		System.out.println();
		// Q12
		System.out.println(convert(730));
		System.out.println(convert(27));
		System.out.println(convert(3));
		System.out.println(convert2(730));
		System.out.println(convert2(27));
		System.out.println(convert2(3));
		//Q13
		System.out.println("Search Young Tableau");
		int[][] table = {{1, 4, 7, 11, 15},
				{2, 5, 8, 12, 19},
				{3, 6, 9, 16, 22},
				{10, 13, 14, 17, 24},
				{18, 21, 23, 26, 30}};
		System.out.println(stepwise(table, 10));
		System.out.println(quadPartition(table, 10, 0, 0, table[0].length - 1, table.length - 1));
		System.out.println(binaryPartition(table, 10, 0, 0, table[0].length - 1, table.length - 1));
		// Q14
		int[] sorted_array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
		TreeNode tree_root = TreeNode.construct(sorted_array, 0, sorted_array.length - 1);
		TreeNode.printLevel(tree_root);
		ArrayList<Integer> list = printEdges(tree_root);
		for(int i = 0; i < list.size(); i++)
			System.out.print(list.get(i) + " ");
		System.out.println();
		// Q15
		System.out.println(Q15replace("a", "a"));
		System.out.println(Q15replace("aa", "aa"));
		System.out.println(Q15replace("aa", "a"));
		System.out.println(Q15replace("aa", "aaa"));
		System.out.println(Q15replace("abc", "abc"));
		System.out.println(Q15replace("abcabc", "abc"));
		System.out.println(Q15replace("abcaabcaabc", "abc"));
		System.out.println(Q15replace("abcdeffdfegabcaaaabcab", "abc"));
		System.out.println(Q15replace("aabaaabaa", "aa"));

		// Q17
		TreeNode root17 = new TreeNode(10);
		root17.left = new TreeNode(5);
		root17.left.left = new TreeNode(1);
		root17.left.right = new TreeNode(8);
		root17.right = new TreeNode(15);
		root17.right.right = new TreeNode(7);
		largestSubtree(root17);
		
		// Test. Pass. test.left will remain 6 no matter how left got changed
		TreeNode test = new TreeNode(5);
		TreeNode left = new TreeNode(6);
		TreeNode left_next = new TreeNode(7);
		test.left = left;
//		left = new TreeNode(8);
		left = left_next;
		
		// Q18
	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值