public class StringAB { private static final String STR_A = "A"; private static final String STR_B = "B"; public static final char CHAR_B = 'B'; public static final char CHAR_A = 'A'; public static void main(String[] args) { String s = generateStringNK(5, 8); System.out.println(s); System.out.println(countABPoints(s, s.length())); } private static String generateStringNK(int N, int K){ int aCount = N / 2; int bCount = N % 2 == 0 ? aCount : aCount + 1; int maxK = aCount * bCount; if (K > maxK) return ""; StringBuilder sb = new StringBuilder(); for (int i = 0; i < aCount; ++i) sb.append(STR_A); for (int i = 0; i < bCount; ++i) sb.append(STR_B); String s = sb.toString(); for (int i = countABPoints(s, N); i > K; --i) s = swapABForDecrement(s, N); return s; } private static int countABPoints(String s, int n) { int bCount = 0; int sum = 0; for (int i = n - 1; i > -1; --i) { if(s.charAt(i) == CHAR_A) { sum += bCount; } else { ++bCount; } } return sum; } private static String swapABForDecrement(String s, int n) { int index = getIndexOfAAfterLastSubstringOfB(s, n); char[] charArray = s.toCharArray(); charArray[index] = CHAR_B; charArray[index + 1] = CHAR_A; return new String(charArray); } private static int getIndexOfAAfterLastSubstringOfB(String s, int n) throws IndexOutOfBoundsException { int indexOfLastB = getIndexOfLastB(s, n); while (true) { --indexOfLastB; if (s.charAt(indexOfLastB) == CHAR_A) return indexOfLastB; } } private static int getIndexOfLastB(String s, int n) { int indexOfLastB = n; do { --indexOfLastB; } while (s.indexOf(STR_B, indexOfLastB) == -1); return indexOfLastB; } }