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];
}