public static String longestCommonSubsequence(String str1, String str2) {
		int[][] lcsMap = new int[str1.length() + 1][str2.length() + 1];
		
		for(int i = 0; i <= str1.length(); i++) {
			lcsMap[i][0] = 0;
		}
		
		for(int j = 0; j <= str2.length(); j++) {
			lcsMap[0][j] = 0;
		}
		
		for(int i = 1; i <= str1.length(); i++) {
			for(int j = 1; j <= str2.length(); j++) {
				if(str1.charAt(i - 1) == str2.charAt(j - 1)) {
					lcsMap[i][j] = lcsMap[i - 1][j - 1] + 1;
				} else {
					lcsMap[i][j] = Math.max(lcsMap[i - 1][j], lcsMap[i][j - 1]);
				}
			}
		}
		
		int i = str1.length();
		int j = str2.length();
		Stack<Character> subsequence = new Stack<Character>();
		StringBuilder sb = new StringBuilder();
		
		while(lcsMap[i][j] > 0) {
			if(str1.charAt(i - 1) == str2.charAt(j - 1)) {
				subsequence.push(str1.charAt(i - 1));
				i--;
				j--;
			} else if(lcsMap[i][j] == lcsMap[i - 1][j]) {
				i--;
			} else {
				j--;
			}
		}
		
		while(!subsequence.isEmpty()) {
			sb.append(subsequence.pop());
		}
		
		return sb.toString();
	}