public String longestPalindrome(String s) {
        String revStr = "";
        for (int i = 0; i < s.length(); ++i) {
            revStr = s.charAt(i) + revStr;
        }

        int[][] state = new int[s.length() + 1][s.length() + 1];
        Mark mark = new Mark();
        Queue<Mark> list = new PriorityQueue<Mark>(s.length());
        for (int i = 0; i < s.length(); ++i) {
            for (int j = 0; j < s.length(); ++j) {
                if (s.charAt(i) == revStr.charAt(j)) {
                    state[i + 1][j + 1] = state[i][j] + 1;
                    if (state[i + 1][j + 1] > mark.max) {
                        mark.max = state[i + 1][j + 1];
                        mark.marki = i;
                        mark.markj = j;
                    }
                }
                else if (state[i][j] > 0) {
                    list.offer(mark);
                    mark = new Mark();
                }
            }
        }
        while (!list.isEmpty()) {
            mark = list.poll();
            if (mark.markj == s.length() - 1 - mark.marki + mark.max - 1)
                break;
        }

        return s.substring(s.length() - 1 - mark.markj, mark.marki + 1);
    }