寫在前面
對於字符串數組,我們一般會爲他們分配兩個長度爲12字節的空間,並把"Hello world"的內容分複製到數組中去,因此它們是兩個初始地址不同的數組,因此這兩個字符串數組的值也不同。
對於字符串來說,我們無需給他們分配內存,只要這兩個常量的值相同,那麼他們就是相同的。
面試題5 替換空格
請實現一個函數,把字符串 s 中的每個空格替換成"%20"。
示例 1:
輸入:s = “We are happy.”
輸出:“We%20are%20happy.”
class Solution {
public String replaceSpace(String s) {
StringBuilder builder = new StringBuilder();
for(char c : s.toCharArray()){
if(c == ' ') builder.append("%20");
//append函數相當於+
else builder.append(c);
}
return builder.toString();
}
}
class Solution {
public String replaceSpace(String s) {
return s.replace(" ","%20");
}
}
class Solution {
public String replaceSpace(String s) {
int length = s.length();
char[] array = new char[length * 3];
int size = 0;
for (int i = 0; i < length; i++) {
char c = s.charAt(i);
if (c == ' ') {
array[size++] = '%';
array[size++] = '2';
array[size++] = '0';
} else {
array[size++] = c;
}
}
String newStr = new String(array, 0, size);
//把array數組從0取到size,然後變爲String
return newStr;
}
}
242. 有效的字母異位詞
給定兩個字符串 s 和 t ,編寫一個函數來判斷 t 是否是 s 的字母異位詞。
示例 1:
輸入: s = “anagram”, t = “nagaram”
輸出: true
示例 2:
輸入: s = “rat”, t = “car”
輸出: false
class Solution {
public boolean isAnagram(String s, String t) {
if(s.length()!= t.length()) return false;
int[] counter = new int[26];
for(int i = 0; i<s.length(); i++){
counter[s.charAt(i)-'a']++;
counter[t.charAt(i)-'a']--;
}
for(int count : counter){
if(count !=0) return false;
}
return true;
}
}
class Solution {
public boolean isAnagram(String s, String t) {
if(s.length() != t.length()) return false;
char[] S = s.toCharArray();
char[] T = t.toCharArray();
Arrays.sort(S);
Arrays.sort(T);
for(int i = 0; i < S.length; i++){
if(S[i] != T[i]) return false;
}
return true;
}
}
409. 最長迴文串
給定一個包含大寫字母和小寫字母的字符串,找到通過這些字母構造成的最長的迴文串。
在構造過程中,請注意區分大小寫。比如 “Aa” 不能當做一個迴文字符串。
注意:
假設字符串的長度不會超過 1010。
示例 1:
輸入:
“abccccdd”
輸出:
7
解釋:
我們可以構造的最長的迴文串是"dccaccd", 它的長度是 7。
class Solution {
//在字符串中有重複的字符,如果重複的字符是奇數,就對稱放
//如果是偶數的話就放中間
//因此這道題就轉變成了求重複字符的數量
public int longestPalindrome(String s) {
//ASCII表 a-z:97-122,A-Z:65-90,0-9:48-57。
// 將每個字母都放在不同的位置上,如果該位置有字母則加1
int[] counter = new int[58];
for(int i = 0; i< s.length(); i++){
counter[s.charAt(i)-'A']++;
}
// a 1 b 1 c 4 d 2 1142
int result = 0;
int mark = 0;//記錄奇數字母的位置
for(int count : counter){
if(count % 2 ==1){
//說明是奇數個
mark+=1;
}
result += count/2; //0021
}
if(mark>0) return result*2+1;
return result*2;
}
}
class Solution {
//在字符串中有重複的字符,如果重複的字符是奇數,就對稱放
//如果是偶數的話就放中間
//因此這道題就轉變成了求重複字符的數量
public int longestPalindrome(String s) {
//hashmap
Map<Character, Integer> map = new HashMap<>();
for(Character c : s.toCharArray()){
map.put(c, map.getOrDefault(c,0)+1);
//getOrDefalut()意爲map中有指定的key就返回對應的value,如果沒有就返回默認值
//而默認值就是第二個參數的值
//上題的意思就是如果有c變量這個字母就輸出其對應的value值,沒有就輸出0
}
int mark =0; int res=0;
for(Integer count : map.values()){
if(count %2 == 1) mark++;
res += count/2;
}
if(mark > 0) return res*2+1;
return res*2;
}
}
205. 同構字符串
給定兩個字符串 s 和 t,判斷它們是否是同構的。
如果 s 中的字符可以被替換得到 t ,那麼這兩個字符串是同構的。
所有出現的字符都必須用另一個字符替換,同時保留字符的順序。兩個字符不能映射到同一個字符上,但字符可以映射自己本身。
示例 1:
輸入: s = “egg”, t = “add”
輸出: true
示例 2:
輸入: s = “foo”, t = “bar”
輸出: false
示例 3:
輸入: s = “paper”, t = “title”
輸出: true
class Solution {
public boolean isIsomorphic(String s, String t) {
return isIso(s,t) && isIso(t,s);
}
public boolean isIso(String s, String t){
if(s.length() != t.length()) return false;
HashMap<Character,Character> map = new HashMap<>();
for(int i = 0 ; i < s.length(); i++){
char c1 = s.charAt(i);
char c2 = t.charAt(i);
if(map.containsKey(c1)){
if(map.get(c1) != c2) return false;
}else{
map.put(c1,c2);
}
}
return true;
}
}
696. 計數二進制子串
給定一個字符串 s,計算具有相同數量0和1的非空(連續)子字符串的數量,並且這些子字符串中的所有0和所有1都是組合在一起的。
重複出現的子串要計算它們出現的次數。
示例 1 :
輸入: “00110011”
輸出: 6
解釋: 有6個子串具有相同數量的連續1和0:“0011”,“01”,“1100”,“10”,“0011” 和 “01”。
請注意,一些重複出現的子串要計算它們出現的次數。
另外,“00110011”不是有效的子串,因爲所有的0(和1)沒有組合在一起。
示例 2 :
輸入: “10101”
輸出: 4
解釋: 有4個子串:“10”,“01”,“10”,“01”,它們具有相同數量的連續1和0。
class Solution {
public int countBinarySubstrings(String s) {
int i = 0;
int j = s.length();
int pre = 0, cur =0;
char[] S = s.toCharArray();
int res =0;
while(i<j){
pre = cur;//把cur記錄到的數字傳給pre
cur =1;//cur繼續從1開始計數
i+=1;
while(i<j && S[i] == S[i-1]){
cur++;//記錄連續0或者連續1的值
i++;
}
res += Math.min(cur, pre);
}
return res;
}
}
392.判斷子序列
給定字符串 s 和 t ,判斷 s 是否爲 t 的子序列。
你可以認爲 s 和 t 中僅包含英文小寫字母。字符串 t 可能會很長(長度 ~= 500,000),而 s 是個短字符串(長度 <=100)。
字符串的一個子序列是原始字符串刪除一些(也可以不刪除)字符而不改變剩餘字符相對位置形成的新字符串。(例如,"ace"是"abcde"的一個子序列,而"aec"不是)。
示例 1:
s = “abc”, t = “ahbgdc”
返回 true.
示例 2:
s = “axc”, t = “ahbgdc”
返回 false.
class Solution {
public boolean isSubsequence(String s, String t) {
int i=0;
int j=0;
while(i < s.length()&& j<t.length()){
if(s.charAt(i)== t.charAt(j)){
i++;
j++;
}else{
j++;
}
}
return i==s.length();
}
}
8. 字符串轉數組
請你來實現一個 atoi 函數,使其能將字符串轉換成整數。
首先,該函數會根據需要丟棄無用的開頭空格字符,直到尋找到第一個非空格的字符爲止。
當我們尋找到的第一個非空字符爲正或者負號時,則將該符號與之後面儘可能多的連續數字組合起來,作爲該整數的正負號;假如第一個非空字符是數字,則直接將其與之後連續的數字字符組合起來,形成整數。
該字符串除了有效的整數部分之後也可能會存在多餘的字符,這些字符可以被忽略,它們對於函數不應該造成影響。
注意:假如該字符串中的第一個非空格字符不是一個有效整數字符、字符串爲空或字符串僅包含空白字符時,則你的函數不需要進行轉換。
在任何情況下,若函數不能進行有效的轉換時,請返回 0。
說明:
假設我們的環境只能存儲 32 位大小的有符號整數,那麼其數值範圍爲 [−231, 231 − 1]。如果數值超過這個範圍,請返回 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) 。
class Solution {
public int myAtoi(String str) {
//將題目分成兩部分:數字之前 和 數字之後
//數字之前需要考慮:1.跳過所有空格;2.非數字字符直接返回0;3.保留正負號信息
//數字之後的字符:如果不是數字,停止轉換
//總體考慮轉換之後的數字是否越界--爲了避免用long
//1.跳過所有空格
str = str.trim();//trim函數去掉字符串兩端的空格
if(str == null || str.length()==0) return 0;
int sign = 1;//用sign來記錄正負符號
int index = 0;//用一個index指針挨個查找當前的character
char c = str.charAt(0);
if(c=='+'){
sign = 1;
index++;
}else if(c=='-'){
sign = -1;
index++;
}
long ans = 0;//用long防止越界,long是int類型長度的二倍`在這裏插入代碼片`
// ans初始爲0,如果數字之前出現字符直接返回0;數字之後也是0.
for(int i = index ; i<str.length(); i++){
//非數字字符
if(!Character.isDigit(str.charAt(i))){
return (int)ans*sign;
}
ans = ans*10+ str.charAt(i)-'0';
//討論數字是否越界
if(sign == 1 && ans>Integer.MAX_VALUE){
return Integer.MAX_VALUE;
}
if(sign == -1 && (-1)*ans<Integer.MIN_VALUE){
return Integer.MIN_VALUE;
}
}
return (int) ans*sign;//return 的時候進行一個強轉
}
}