java字符串算法題

1.編寫一個函數,其作用是將輸入的字符串反轉過來。輸入字符串以字符數組 char[] 的形式給出。

不要給另外的數組分配額外的空間,你必須原地修改輸入數組、使用 O(1) 的額外空間解決這一問題。

你可以假設數組中的所有字符都是 ASCII 碼錶中的可打印字符。

輸入:["h","e","l","l","o"]
輸出:["o","l","l","e","h"]

思路解析:取開始和中間索引一起遞增然後交換,另一種是頭尾交換向中間靠攏

public void reverseString(char[] s) {
	int len=s.length;
	for(int i=0;i<len/2;i++){
		char temp=s[i];
		s[i]=s[len-1-i];
		s[len-1-i]=temp;
	}
}
//
 public void reverseString(char[] s) {
 	int p1 = -1, p2 = s.length;
 	while(++p1 < --p2){
 		char temp = s[p1];
 		s[p1] = s[p2];
 		s[p2] = temp;
 	}
 }

 

2.給出一個 32 位的有符號整數,你需要將這個整數中每位上的數字進行反轉。

輸入: 123
輸出: 321

輸入: -123
輸出: -321

輸入: 120
輸出: 21

注意:
假設我們的環境只能存儲得下 32 位的有符號整數,則其數值範圍爲 [−231,  231 − 1]。
請根據這個假設,如果反轉後整數溢出那麼就返回 0。

答題感受:一道字符串的題目,官解卻沒用字符串

思路解析:將整數轉爲字符串在翻轉,轉爲整數時捕獲異常,可能捕獲異常不是讓所有人滿意的處理方式。當然還有一種就是每次彈出最後一位放在新數首位重新組合,只要利用最大數除以10判斷就不會溢出了

public int reverse(int x) {
	boolean bol=false;
	if(x<0){
		x=-x;
		bol=true;
	}
	String str1=String.valueOf(x);
	String str2="";
	int len=str1.length();
	for(int i=len-1;i>=0;i--){
		str2+=str1.charAt(i);
	}
	try{
		x=Integer.parseInt(str2);
		if(bol){
			return -x;
		}         
	}catch(Exception e){
		return 0;
	}  
	return x;
}
//
public int reverse(int x) {
	int rev = 0;
	while (x != 0) {
		int pop = x % 10;
		x /= 10;
		if (rev > Integer.MAX_VALUE/10 || (rev == Integer.MAX_VALUE / 10 && pop > 7)) return 0;
		if (rev < Integer.MIN_VALUE/10 || (rev == Integer.MIN_VALUE / 10 && pop < -8)) return 0;
		rev = rev * 10 + pop;
	}
	return rev;
}

 

3.給定一個字符串,找到它的第一個不重複的字符,並返回它的索引。如果不存在,則返回 -1。

s = "leetcode"
返回 0.

s = "loveleetcode",
返回 2.

注意事項:您可以假定該字符串只包含小寫字母。

思路解析:構造數組,每個字母轉換爲整數對應自己的位置並存入+1,第二次遍歷查找值爲1的索引值。map實現效果相同

 public int firstUniqChar(String s) {
 	int[] times = new int[256];
 	for (char c : s.toCharArray()) {
 		times[c - 'a']++;
 	}
 	for (int i = 0; i < s.length(); i++) {
 		if (times[s.charAt(i) - 'a'] == 1) {
 			return i;
 		}
 	}
 	return -1;
 }

 

4.給定兩個字符串 s 和 t ,編寫一個函數來判斷 t 是否是 s 的一個字母異位詞。

輸入: s = "anagram", t = "nagaram"
輸出: true

輸入: s = "rat", t = "car"
輸出: false

說明:
你可以假設字符串只包含小寫字母。

進階:
如果輸入字符串包含 unicode 字符怎麼辦?你能否調整你的解法來應對這種情況?

思路解析:與上題方法相同,進階暫時沒看

public boolean isAnagram(String s, String t) {
	int[] nums1=new int[26];
	int[] nums2=new int[26];
	for(char c:s.toCharArray()){
		nums1[c-'a']++;
	}
	for(char c:t.toCharArray()){
		nums2[c-'a']++;
	} 
	for(int i=0;i<26;i++){
		if(nums2[i]!=nums1[i]){
			return false;
		}
	}     
	return true;   
}   

 

5.給定一個字符串,驗證它是否是迴文串,只考慮字母和數字字符,可以忽略字母的大小寫。

說明:本題中,我們將空字符串定義爲有效的迴文串。

輸入: "A man, a plan, a canal: Panama"
輸出: true

輸入: "race a car"
輸出: false

思路解析:兩種解法道理都一樣,但正則好像慢了點

 public boolean isPalindrome(String s) {
 	String str=s.toLowerCase().replaceAll("[^0-9a-z]","");
 	for(int i=0;i<str.length();i++){
 		if(str.charAt(i)!=str.charAt(str.length()-1-i)){
 			return false;
 		}
 	}
 	return true;  
 }
//雙指針
public boolean isPalindrome(String s) {
	if (s.length()==0||s.length()==1)return true;
	s = s.toLowerCase();
	int i =0,j=s.length()-1;
	while (i<j){
		while ((s.charAt(i) < '0' || s.charAt(i) > '9') && (s.charAt(i) < 'a' || s.charAt(i) > 'z') && i < j) i++;
		while ((s.charAt(j) < '0' || s.charAt(j) > '9') && (s.charAt(j) < 'a' || s.charAt(j) > 'z') && i < j) j--;
		if (s.charAt(i) != s.charAt(j)) return false;
		i++;j--;
	}
	return true;
}

 

6.請你來實現一個 atoi 函數,使其能將字符串轉換成整數。

首先,該函數會根據需要丟棄無用的開頭空格字符,直到尋找到第一個非空格的字符爲止。

當我們尋找到的第一個非空字符爲正或者負號時,則將該符號與之後面儘可能多的連續數字組合起來,作爲該整數的正負號;假如第一個非空字符是數字,則直接將其與之後連續的數字字符組合起來,形成整數。

該字符串除了有效的整數部分之後也可能會存在多餘的字符,這些字符可以被忽略,它們對於函數不應該造成影響。

注意:假如該字符串中的第一個非空格字符不是一個有效整數字符、字符串爲空或字符串僅包含空白字符時,則你的函數不需要進行轉換。

在任何情況下,若函數不能進行有效的轉換時,請返回 0。

說明:

假設我們的環境只能存儲 32 位大小的有符號整數,那麼其數值範圍爲 [−231,  231 − 1]。如果數值超過這個範圍,qing返回  INT_MAX (231 − 1) 或 INT_MIN (−231) 

示例 1:

輸入: "42"
輸出: 42
示例 2:

輸入: "   -42"
輸出: -42
解釋: 第一個非空白字符爲 '-', 它是一個負號。
     我們儘可能將負號與後面所有連續出現的數字組合起來,最後得到 -42 。
示例 3:

輸入: "4193 with words"
輸出: 4193
解釋: 轉換截止於數字 '3' ,因爲它的下一個字符不爲數字。
示例 4:

輸入: "words and 987"
輸出: 0
解釋: 第一個非空字符是 'w', 但它不是數字或正、負號。
     因此無法執行有效的轉換。
示例 5:

輸入: "-91283472332"
輸出: -2147483648
解釋: 數字 "-91283472332" 超過 32 位有符號整數範圍。 
     因此返回 INT_MIN (−231) 。

思路解析:首先解決空字符,然後是正負號先取下來,接着看字符是否是數字然後拼接數字,不是數字是就退出

public int myAtoi(String str) {
        // ex:"5900萬臺智能手機發貨量"
        String strs = str.trim();
        if(strs == null || "".equals(strs))   return 0;
        char Initials = strs.charAt(0);
        int res = 0;
        boolean isPos = Initials != '-' || Initials == '+' ;
        int i = 0;
        // 若首元素是符號則索引從1開始
        i = (Initials == '+' || Initials == '-') ? 1 : 0;
        // System.out.print(i);
        for (; i < strs.length(); i++)  {
            // 從外面已判斷到首元素是否是標記,下面條件作爲其後緊接着的元素的是否爲數字,
            // 否,則直接跳出循環,直接返回結果0
            if(!Character.isDigit(strs.charAt(i))) break;
            else{
                int right = strs.charAt(i) - '0';
                // System.out.println((Integer.MAX_VALUE - right) / 10);
                if (res > (Integer.MAX_VALUE - right) / 10) { 
                    return isPos ? Integer.MAX_VALUE : Integer.MIN_VALUE;
                }
                res = res * 10 + right;   // 轉換的核心思路
            }
        }      
       return isPos ? res : -res;
}

 

7.給定一個 haystack 字符串和一個 needle 字符串,在 haystack 字符串中找出 needle 字符串出現的第一個位置 (從0開始)。如果不存在,則返回  -1。 

示例 1:

輸入: haystack = "hello", needle = "ll"
輸出: 2
示例 2:

輸入: haystack = "aaaaa", needle = "bba"
輸出: -1
說明:

當 needle 是空字符串時,我們應當返回什麼值呢?這是一個在面試中很好的問題。

對於本題而言,當 needle 是空字符串時我們應當返回 0 。這與C語言的 strstr() 以及 Java的 indexOf() 定義相符。

思路解析:最簡單的解法

public int strStr(String haystack, String needle) {
        if (needle.equals(""))
            return 0;
        else if (!haystack.contains(needle))
            return -1;
        else {
            return haystack.indexOf(needle);
        }
}

 

8.報數序列是一個整數序列,按照其中的整數的順序進行報數,得到下一個數。其前五項如下:

1.     1
2.     11
3.     21
4.     1211
5.     111221

1 被讀作  "one 1"  ("一個一") , 即 11。
11 被讀作 "two 1s" ("兩個一"), 即 21。
21 被讀作 "one 2",  "one 1" ("一個二" ,  "一個一") , 即 1211。

給定一個正整數 n(1 ≤ n ≤ 30),輸出報數序列的第 n 項。

注意:整數順序將表示爲一個字符串。

示例 1:

輸入: 1
輸出: "1"
示例 2:

輸入: 4
輸出: "1211"

思路解析:外層while循環爲檢索字符串,內層用while循環計數相同數字的個數,拼接的數字爲計數的數字加被計數的數字

public String countAndSay(int n) {
        String str="1";
        for(int i=0;i<n-1;i++){
            int j=0;           
            String temp="";
            while(j<str.length()){
                int value=1;
                while(j+1<str.length()&&str.charAt(j)==str.charAt(j+1)){
                    value++;
                    j++;
                }               
                temp=temp+value+str.charAt(j);                    
                j++;
         }     
         str=temp;
    }      
    return str;
}

 

9.編寫一個函數來查找字符串數組中的最長公共前綴。如果不存在公共前綴,返回空字符串 ""

示例 1:

輸入: ["flower","flow","flight"]
輸出: "fl"
示例 2:

輸入: ["dog","racecar","car"]
輸出: ""
解釋: 輸入不存在公共前綴。
說明:

所有輸入只包含小寫字母 a-z 。

思路解析:第一種是從所有字符的後往前找,第二種是從前往後找

public String longestCommonPrefix(String[] strs) {
    if (strs == null || strs.length == 0) return "";
    for (int i = 0; i < strs[0].length() ; i++){
        char c = strs[0].charAt(i);
        for (int j = 1; j < strs.length; j ++) {
            if (i == strs[j].length() || strs[j].charAt(i) != c)
                return strs[0].substring(0, i);             
        }
    }
    return strs[0];
}
//
public String longestCommonPrefix(String[] strs) {
        if (strs == null || strs.length == 0) return "";
        for (int i = 0; i < strs[0].length() ; i++){
            char c = strs[0].charAt(i);
            for (int j = 1; j < strs.length; j ++) {
                if (i == strs[j].length() || strs[j].charAt(i) != c)
                    return strs[0].substring(0, i);             
            }
        }
        return strs[0];
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章