字符串中的最後一個唯一字符

字符串中的最後一個唯一字符

分析,類似的題目有 字符串中的第一個唯一字符

思路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;
    }

注意:

  1. HashMap裏面存放的鍵值對是沒有被記錄插入順序的,故使用LinkedHashMap;
  2. TreeMap中的元素默認按照keys的自然排序排列。(對Integer來說,其自然排序就是數字的升序;對String來說,其自然排序就是按照字母表排序)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章