給定兩個字符串s和t,確定它們是否是同構的。
如果s中的字符可以替換爲t,則兩個字符串是同構的。
所有出現的字符必須替換爲另一個字符,同時保留字符的順序。沒有兩個字符可以映射到相同的字符,但字符可以映射到自身。
例1:
輸入: s = “egg”, t =“add”
輸出: true
例2:
輸入: s = “foo”, t =“bar”
輸出: false
可以使用HashMap,把字符t變成字符串
public boolean isIsomorphic(String s, String t) {
Map m = new HashMap();
for (Integer i=0; i<s.length(); ++i)
if (m.put(s.charAt(i), i) != m.put(t.charAt(i)+"", i))
return false;
return true;
}
如果陣列單調遞增或單調遞減,則陣列是單調的。
數組A是單調的,如果所有的增加i <= j,A[i] <= A[j]。A如果對所有人來說i <= j,數組是單調減少的A[i] >= A[j]。
返回true當且僅當給定的數組A是單調的。
例1:
輸入:[1,2,2,3]
輸出:true
例2:
輸入:[6,5,4,4]
輸出:true
public boolean isMonotonic(int[] A) {
boolean in = true, de = true;
for(int i = 0; i < A.length-1; i++) {
if(A[i] > A[i+1]) in = false;
else if(A[i] < A[i+1]) de = false;
}
return in || de;
}
給定兩個串 S 並T,返回,如果他們是平等的,當兩者都輸入到空的文本編輯器。#表示退格字符。
例1:
輸入: S = “ab#c”,T = “ad#c”
輸出:true
說明:S和T都變爲“ac”。
例2:
輸入: S = “ab ##”,T = “c#d#”
輸出:true
說明:S和T都變爲“”。
可以考慮使用堆棧來進行操作
public boolean backspaceCompare(String S, String T) {
for (int i = S.length() - 1, j = T.length() - 1;; i--, j--) {
for (int b = 0; i >= 0 && (b > 0 || S.charAt(i) == '#'); --i) b += S.charAt(i) == '#' ? 1 : -1;
for (int b = 0; j >= 0 && (b > 0 || T.charAt(j) == '#'); --j) b += T.charAt(j) == '#' ? 1 : -1;
if (i < 0 || j < 0 || S.charAt(i) != T.charAt(j)) return i == -1 && j == -1;
}
}
給定一個整數數組 nums ,找到一個具有最大和的連續子數組(子數組最少包含一個元素),返回其最大和。
public int maxSubArray(int [] nums) {
if(nums == null||nums.length == 0)
return 0;
int current = nums[0],max = nums[0];
for(int i = 1;i < nums.length;i++){
current = Math.max(current + nums[i], nums[i]);
max = Math.max(current, max);
}
return max;
編寫一個程序判斷給定的數是否爲醜數。
醜數就是隻包含質因數 2, 3, 5 的正整數。
示例 1:
輸入: 64.
輸出: true
解釋: 6 = 2 × 3
示例 2:
輸入: 8
輸出: true
解釋: 8 = 2 × 2 × 2
示例 3:
輸入: 14
輸出: false
解釋: 14 不是醜數,因爲它包含了另外一個質因數 7。
說明:
1 是醜數。輸入不會超過 32 位有符號整數的範圍: [−231, 231 − 1]。
public boolean isUgly(int num) {
while(num % 2 == 0)
num = num / 2;
while(num % 3 == 0)
num = num / 3;
while(num % 5 == 0)
num = num / 5;
return (num == 1) ? false : true;
給定一個由整數組成的非空數組所表示的非負整數,在該數的基礎上加一。
public int [] plusOne(int [] digits) {
int len = digits.length;
for(int i = len - 1;i >= 0;i--) {
if(digits[i] < 9) {
digits[i]++;
return digits;
}
digits[i] = 0;
}
int [] nums = new int [len + 1];
nums[0] = 1;
return nums;
}
給定已排序的鏈接列表,刪除所有重複項,使每個元素只出現一次。
例1:
輸入: 1-> 1-> 2
輸出: 1-> 2
例2:
輸入: 1-> 1-> 2-> 3-> 3
輸出: 1-> 2-> 3
public ListNode deleteDuplicates(ListNode head) {
if(head == null||head.next == null) return head;
ListNode node = head;
while(node.next != null) {
if(node.val == node.next.val) node.next = node.next.next;
else node = node.next;
}
return head;
給定一個非空整數數組,除了某個元素只出現一次以外,其餘每個元素均出現兩次。找出那個只出現了一次的元素
public int singleNumber(int [] nums){
int len = nums.length;
int max = nums[0];
int a = 0;
for(int i = 1;i < len;i++){
if(max < nums[i])
max = nums[i];
}
int [] acg = new int [max];
for(int i = 0;i < max + 1;i++)
acg[i] = 0;
for(int j = 0;j < len;j++) {
acg[nums[j]]++;
}
for(int i = 0;i < max + 1;i++) {
if(acg[i] == 1)
a = i;
}
return a;
}
9.組合總數:
給定候選數字(candidates)和目標數字(target)的集合,找到candidates 候選數字相加的所有唯一組合target。
每個數字candidates 只能在組合中使用一次。
注意:
所有數字(包括target)都是正整數。
解決方案集不得包含重複的組合。
例1:
輸入: candidate = [10,1,2,7,6,1,5],target = 8,
解決方案集是:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
例2:
輸入:候選= [2,5,2,1,2],目標= 5,
解集是:
[
[1,2,2],
[5]
]
可以考慮使用回溯算法,創建一個遞歸樹,使用基於元素的回溯法,從小到大,並決定我在結果組合中包含的每個元素的副本數量。
public List<List<Integer>> combinationSum2(int[] candidates, int target) {
Arrays.sort (candidates);
List<List<Integer>> res_lss = new ArrayList<> ();
search (candidates, 0, target, res_lss, new ArrayDeque<> ());
return res_lss;
}
void search (int[] candidates, int index, int remain, List<List<Integer>> lss, Deque<Integer> accum) {
if (remain == 0) {
lss.add (new ArrayList<> (accum));
return;
}
if (index >= candidates.length) {
return;
}
int next = index;
while (next < candidates.length && candidates[next] == candidates[index])
next++;
int num = next - index, cur = candidates[index], i;
for (i = 0; i <= num && remain >= i * cur; i++) {
if (i > 0)
accum.push (cur);
search (candidates, next, remain - i * cur, lss, accum);
}
assert accum.size () >= i - 1;
for (int j = 0; j < i - 1; j++)
accum.pop ();
}
10.轉移信件:
我們有一串S小寫字母和一個整數數組shifts。
調用一個字母的移位,字母表中的下一個字母,(環繞以便’z’變爲’a’)。
例如,shift(‘a’) = 'b’和shift(‘t’) = ‘u’,和shift(‘z’) = ‘a’。
現在,每一個shifts[i] = x,我們要移後的第一i+1 字母S,x倍。
S應用所有這些轉換後返回最後一個字符串。
例1:
輸入: S =“abc”,shift = [3,5,9]
輸出: “rpl”
說明:
我們從“abc”開始。
將S的前1個字母移動3後,我們有“dbc”。
將S的前2個字母移動5後,我們有“igc”。
在將S的前三個字母移動9後,我們得到了“rpl”,即答案。
注意:
1 <= S.length = shifts.length <= 20000
0 <= shifts[i] <= 10 ^ 9
class Solution {
public String shiftingLetters(String S, int[] shifts) {
char[] arr = S.toCharArray();
int shift = 0;
for (int i = arr.length - 1; i >= 0; i--) {
shift = (shift + shifts[i]) % 26;
arr[i] = (char)((arr[i] - 'a' + shift) % 26 + 'a');
}
return new String(arr);
}
}
11.字符串中的排序:
給定兩個字符串s1和s2,如果s2包含s1的排列,則寫一個函數返回true 。換句話說,第一個字符串的排列之一是第二個字符串的子字符串。
例1: 輸入: s1 =“ab”s2 =“eidbaooo” 輸出: True 說明: s2包含s1(“ba”)的一個排列。
例2:輸入: s1 =“ab”s2 =“eidboaoo” 輸出: False
可以考慮先創建一個保存字符串的數組,再創建一個移動數組,在每次迭代期間告訴數組是否相等
public boolean checkInclusion(String s1, String s2) {
int n1=s1.length(),n2=s2.length();
int[] f1=new int[26];
for(int i=0;i<n1;i++) f1[s1.charAt(i)-'a']++;
int[] f2=new int[26];
for(int j=0;j<n2;j++){
f2[s2.charAt(j)-'a']++;
if(j>=n1) f2[s2.charAt(j-n1)-'a']--;
if(Arrays.equals(f2,f1)) return true;
}
return false;
}
12.實現 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) 。
想法:可以通過條件逐一進行條件判斷
public class Solution {
public int myAtoi(String str) {
int i = 1;
String s = "";
if(str.length() == 0||str == null)
return 0;
while(i <= str.length()) {
if((int)str.charAt(i) != 32) {
if((int)str.charAt(i) > 48||(int)str.charAt(i) <= 57)
s += str.charAt(i);
else if((int)str.charAt(i) == 48)
s += "";
else
return 0;
break;
}
i++;
}
i++;
while(i <= str.length()) {
if((int)str.charAt(i) >= 48||(int)str.charAt(i) <= 57)
s += str.charAt(i);
i++;
}
long t = Long.parseLong(s);
if(t < Math.pow(-2, 31)||t > Math.pow(2, 31))
return 0;
else
return (int)t;
}
public static String stringToString(String input) {
if (input == null) {
return "null";
}
return Json.value(input).toString();
}
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String line;
while ((line = in.readLine()) != null) {
String str = stringToString(line);
int ret = new Solution3().myAtoi(str);
String out = String.valueOf(ret);
return out;
}
}
13.救人的小船:
第i- 人有重量people[i],每艘船可以承受最大重量limit。
每艘船最多同時載有2人,前提是這些人的重量總和最多limit。
返回攜帶每個人的最小船隻數量。(保證每個人都可以乘船。)
例1:
輸入:人= [1,2],限制= 3 輸出:1 說明: 1船(1,2) 例2:
輸入: people = [3,2,2,1],limit = 3 輸出:3 說明:3艘船(1,2),(2)和(3) 例3:
輸入:人= [3,5,3,4],限制= 5 輸出:4 說明:4船(3),(3),(4),(5) 注意:
1 <= people.length <= 50000 1 <= people[i] <= limit <= 30000
可以從兩端開始排序,總是移動高端,但低端取決於它是否可以塞進高端的船
public int numRescueBoats(int[] people, int limit) {
Arrays.sort(people);
int ans = 0;
for (int hi = people.length - 1, lo = 0; hi >= lo; --hi, ++ans) {
if (people[lo] + people[hi] <= limit) { ++lo; }
}
return ans;
}