[Java] Easy to understand solution with detailed explanation and pictures
The idea is to figure out the number of substrings each character can be a part of while remaining the only unique character. We then get the answer by summing 
The idea is to figure out the number of substrings each character can be a part of while remaining the only unique character. We then get the answer by summing up the results of every character.\n\nFiguring out the number of substrings a character can be a part of can be done by finding out:\n1) the number of characters between the current character and its duplicate on the left, if any\n2) the number of characters between the current character and its duplicate on the right, if any\n\nThis is because the current character can contribute to all substrings as long as it isn\'t contaminated by its duplicate.\n\nLet\'s look at the example \'LEETCODE\' and the following graph:\n```\n\t\t\tL   E   E*  T   C   O   D   E**\nLeft        0   1   0   3   4   5   6   4\nRight       7   0   4   4   3   2   1   0\n```\nThe above graph tells us the number of non-duplicate characters between the current character and a potential duplicate on the left AND on the right. If there are no duplicates, it will just be the remaining characters on the left and right\n```\nFor L:\n   Left: There is no duplicate on the left. Since it is the first character in the string. There are also no characters on it\'s left. Therefore, we use 0.\n   Right: There are no duplicates on the right, so we will use the number of remaining characters on the right to the end of the array, which is 7.\n```\n   \n```\nFor E*:\n   Left: E* sits immediately next to it\'s duplicate tn the left, therefore, there are no other characters to its left. We use 0\n   Right: There are 4 characters between E* and E**, its duplicate on the right. We use 4.\n```\n\n```\nFor E**\n   Left: There are 4 characters between E** and E*, its duplicate on the left.\n   Right: Since E** is the last character in the string, There can be no additional characters on the right. Therefore, we use 0.\n```\n\nNow that we understand that, how is that going to help us?\n\nTake a look at what we can form:\n![image](https://assets.leetcode.com/users/images/6d87e2dd-53f3-4c3b-bbf1-070d1ec6d730_1638341906.3830788.png)\n\n\nDo you see what\'s happening here? Each character can contribute:\n1) 1 + **Left** amount of characters (or the number of characters between this current character and it\'s duplicate on the left, if any) to all the substrings from the left\n3)  1 + **Left** amount of characters (same number) to **Right** number of substrings to it\'s right (or the number of characters betwen this current character and it\'s duplicate on the right)\n\nConfused? Don\'t worry, let\'s take a look again.\n\nHow many characters can T contribute to all the substrings from the left?\n![image](https://assets.leetcode.com/users/images/09709a87-15d5-4c4e-9b62-99ed4749ce6f_1638342466.02651.png)\n\nSince T has no duplicates to the left, it can contribute to ALL the substrings from the left, and let\'s not forget T itself is a substring:\n![image](https://assets.leetcode.com/users/images/c5a43605-05a1-407f-b77c-1ddf92724e9e_1638342536.1277936.png)\n\nThis means that T can contribute 1 + **Left** T\'s where 1 is T itself and Left is the number of non-duplicate characters on the left, or in other words, also the number of substrings forming from the left.\n\nOkay, how many characters can T contribute to the substrings to the right (starting from T)?\n\nThat\'s very simple, it can contribute 1 + **Left** T\'s (same number) to ALL the subsequent substrings to the right until its duplicate. Since it doesn\'t have any duplicates, it can contribute to all of them:\n![image](https://assets.leetcode.com/users/images/b503673a-3337-4dfe-8f73-17874cd19242_1638342897.4147243.png)\n\nWhat if there are duplicates? Let\'s take a look. How many characters can E* contribute?\n![image](https://assets.leetcode.com/users/images/1e94cfe0-49c3-4bf1-8754-5b6bfef032fe_1640152292.0563474.png)\n\nE* can contribute 1 + **Left** E*\'s to all the substrings from the left\n\nBUT in this case, **Left** is zero since E* sits directly next to it\'s duplicate to the left, which is E. This means it cannot contribute to any of the substrings coming from the left. However, it can contribute to the substring that it started itself, so 1 + **Left**, where 1 is the substring just formed and **Left** is zero, so we get 1.\n\nE* can contribute the same number of E*\'s (one) to all the substrings to its right, UNTIL we encounter it\'s duplicate, E**. In other words, it can contribute 1 + **Left** to all the characters between itself and E**, so \n`1 + Left + (Right x (1 + Left)) -> 1 + 0 + (4*1+0) = 5`\n\nSo how many characters can E** contribute? \nE** can contribute 1 + **Left** to some of the substring from the left, which is the distance between E** and E* + 1, in other words, all the substrings formed from the left that has not touched E*\nE** can not contribute to the right since there aren\'t any characters remaining\n![image](https://assets.leetcode.com/users/images/e10250d6-6b53-4623-adeb-8544e0626363_1638344750.5535269.png)\n\n\nHere is the code:\n```\n    public static int uniqueLetterString(String s) {\n        Map<Character, ArrayList<Integer>> indexMap = new HashMap<>();\n\t\t\n\t\t//collect all the indices of each character and add it to a list\n        for(int i = 0; i < s.length(); i++) {\n            char c = s.charAt(i);\n            indexMap.computeIfAbsent(c, k-> new ArrayList<>()).add(i);\n        }\n\n        int res = 0;\n\n        for(Map.Entry<Character, ArrayList<Integer>> kv: indexMap.entrySet()) {\n\t\t\n\t\t\t//each character\'s occurence in String s\n            var allOccurrences = kv.getValue();\n            for(int i = 0; i < allOccurrences.size(); i++) {\n                int currentIndex = allOccurrences.get(i);\n\t\t\t\t\n\t\t\t\t//if this is the first occurence, then the number of characters on the left is just it\'s current Index\n\t\t\t\t//otherwise if it is not the first occurence, the number of characters on the left between this and its duplicate\n\t\t\t\t//is just the difference between the current index and the previous index - 1\n                int left = i == 0 ? currentIndex : currentIndex - allOccurrences.get(i-1) - 1;\n\t\t\t\t\n\t\t\t\t//if this is the last occurence, then the number of characters on the right is just the length of the string minus the current index - 1\n\t\t\t\t//otherwise, if it is not the first occurence, then it will just be the difference between this and the index of its duplicate - 1\n                int right = i == allOccurrences.size() - 1 ? s.length() - currentIndex - 1 : allOccurrences.get(i+1) - currentIndex - 1;\n\t\t\t\t\n\t\t\t\t//the number that this character can contribute to the final result\n\t\t\t\t//is the number of characters that it can contribute to all the substrings built from the left, excluding the substrings that includes it\'s duplicate, if any\n\t\t\t\t//plus\n\t\t\t\t//it can contribute the same number of characters to all the substrings built from here to it\'s next duplicate, if any\n                res += 1 + left + (right * (left + 1));\n            }\n        }\n\n        return res;\n    }\n```
[]