字符串中的最後一個唯一字符
分析,類似的題目有 字符串中的第一個唯一字符
思路1: 如果字符的indexOf的值等於lastIndexOf相等,說明該字符出現一次
思路2:新建一個數組記錄次數;
思路3:用HashMap 存儲鍵值對,value等於1,說明僅僅出現一次。(應該使用LinkedHashMap,爲什麼,請往下看?)
故問題相當於原問題的類似的問題。
解法一:用到字符串中某字符的indexOf的值等於lastIndexOf
將字符串翻轉,字符串長度爲len, 如果字符的indexOf的值等於lastIndexOf相等,令爲i;
則字符串中的最後一個唯一字符的索引爲 len-1-i;
代碼如下:
public class LastOnly {
public static void main(String[] args) {
String str="asdad";
StringBuffer s = new StringBuffer(str); //String轉換爲StringBuffer
String strTemp=s.reverse().toString();//StringBuffer翻轉後轉換爲String
LastOnly lastOnly=new LastOnly();
System.out.println(lastOnly.findOnly(strTemp));
}
public int findOnly(String str){
int len=str.length();
for(int i=0;i<len;i++){
if(str.lastIndexOf(str.charAt(i))==str.indexOf(str.charAt(i))){
return len-i-1;
}
}
return -1;
}
}
需要注意的是,要用到StringBuffer類 的reverse方法,而且反轉後的字符爲StringBuffer 類,需要還原成String類。
String str="asdad";StringBuffer s = new StringBuffer(str); //String轉換爲
StringBufferString strTemp=s.reverse().toString();//StringBuffer翻轉後轉換爲String
解法二、:若要求時間複雜度,那麼空間換時間,用一個數組存放每個字符出現的次數
nums[s.charAt(i)]++;//nums[value]存儲的是字符出現的次數,value 爲字符s.charAt(i)
字符串長度爲len,故遍歷數組nums時候,只需要遍歷前len個元素即可
爲了得到最後一個唯一字符,可以逆序遍歷
public class LastOnly {
public static void main(String[] args) {
String str="asdad12";
int index=firstUniqChar(str);
System.out.println(index);//打印索引
char ch=str.charAt(index);//索引對應在字符串中的字符
System.out.println(ch);
}
//得到字符串的索引
public static int firstUniqChar(String str) {
int[] nums = new int[256];//建一個比字符串大的數組,用來存儲字符出現的次數
int index=-1;//初始化索引
// Arrays.fill(nums,0);//初始化數組nums爲0,非必須,會自動初始化
for(int i=0;i<str.length();i++){
nums[s.charAt(i)]++;//nums[value]存儲的是字符出現的次數,value 爲字符s.charAt(i)
}
for(int j=str.length()-1;j>=0;j--){//從後往前遍歷,只需要遍歷nums數組的
if(nums[s.charAt(j)]==1){
index=j;
break;//找到一個就跳出循環
}
}
return index;
}
}
解法三、:若不要求時間複雜度,可以建一個數組flag標記字符是否重複出現,若重複出現,該索引位標記爲1
public int firstUniqChar(String s) {//時間複雜度o(n^2)
char[] c = s.toCharArray();
int[] flag = new int[c.length];//數組flag標記字符是否重複出現
int index = -1;
for(int i = 0 ; i < c.length; i++){
for(int j = i+1; j < c.length; j++){
if(c[i] == c[j]){
flag[i] = 1;
flag[j] = 1;
}
}
}
for(int i = flag.length-1 ;i >=0 ; i--){
if(flag[i] == 0){//flag位爲0,表示未重複出現
index = i;
return index;
}
}
return index;
}
注 :
解法二、三參考字符串中的第一個唯一字符
解法四、:若不要求時間複雜度,可以建一個數組flag標記字符是否重複出現,若重複出現,該索引位標記爲1
利用LinkedHashMap<Character,Integer> ,用value記錄出現的次數。
Linked內部含有一個private transient Entry header;來記錄元素插入的順序或者是元素被訪問的順序
private static int firstUniqChar(String str) {
LinkedHashMap<Character,Integer> map=new LinkedHashMap<>();
int count=1;
for(int i=0;i<str.length();i++){
char c=str.charAt(i);
if(map.containsKey(c)){
count++;
map.put(c,count);
}else {
map.put(c,1);
}
}
for(int j=str.length()-1;j>=0;j--){
if(map.get(str.charAt(j))==1){
return j;
}
}
return -1;
}
注意:
- HashMap裏面存放的鍵值對是沒有被記錄插入順序的,故使用LinkedHashMap;
- TreeMap中的元素默認按照keys的自然排序排列。(對Integer來說,其自然排序就是數字的升序;對String來說,其自然排序就是按照字母表排序)