205. 同构字符串
给定两个字符串 s 和 t,判断它们是否是同构的。
如果 s 中的字符可以被替换得到 t ,那么这两个字符串是同构的。
所有出现的字符都必须用另一个字符替换,同时保留字符的顺序。两个字符不能映射到同一个字符上,但字符可以映射自己本身。
示例:
输入: s = “egg”, t = “add”
输出: true
class Solution {
public boolean isIsomorphic(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++){
if(!map.containsKey(s.charAt(i))){
if(map.containsValue(t.charAt(i)))
return false;
map.put(s.charAt(i), t.charAt(i));
}else{
if(map.get(s.charAt(i))!=t.charAt(i))
return false;
}
}
return true;
}
}
class Solution {
public boolean isIsomorphic(String s, String t) {
char[] tempS = new char[127];
char[] tempT = new char[127];
char[] S = s.toCharArray();
char[] T = t.toCharArray();
int length = s.length();
for(int i = 0; i < length; i++) {
if(tempS[S[i]] != '\0' || tempT[T[i]] != '\0') {
if(tempS[S[i]] != T[i])
return false;
}else{
tempS[S[i]] = T[i];
tempT[T[i]] = S[i];
}
}
return true;
}
}
219. 存在重复元素 II
给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums [i] = nums [j],并且 i 和 j 的差的绝对值不大于 k。
示例:
输入: nums = [1,2,3,1,2,3], k = 2
输出: false
class Solution {
public boolean containsNearbyDuplicate(int[] nums, int k) {
Set<Integer> set = new HashSet<>();
for (int i = 0; i < nums.length; ++i) {
if (set.contains(nums[i])) return true;
set.add(nums[i]);
if (set.size() > k)
set.remove(nums[i - k]);
}
return false;
}
}
268. 缺失数字
给定一个包含 0, 1, 2, …, n 中 n 个数的序列,找出 0 … n 中没有出现在序列中的那个数。
示例:
输入: [9,6,4,2,3,5,7,0,1]
输出: 8
class Solution {
public int missingNumber(int[] nums) {
// 等差数列求和公式
int expectedSum = nums.length*(nums.length + 1)/2;
int sum = 0;
for(int i : nums)
sum += i;
return expectedSum-sum;
}
}
class Solution {
public int missingNumber(int[] nums) {
int missing = nums.length;
for (int i = 0; i < nums.length; i++)
missing ^= i ^ nums[i];
return missing;
}
}
389. 找不同
给定两个字符串 s 和 t,它们只包含小写字母。
字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母。
请找出在 t 中被添加的字母。
示例:
输入:
s = “abcd”
t = “dbcae”
输出:
e
解释:
‘e’ 是那个被添加的字母。
class Solution {
public char findTheDifference(String s, String t) {
char res =0;
for(int i = 0; i < s.length(); i++)
res^=s.charAt(i);
for(int i = 0; i < t.length(); i++)
res^=t.charAt(i);
return res;
}
}
class Solution {
public char findTheDifference(String s, String t) {
int sum = 0;
for (char c : t.toCharArray())
sum += c;
for (char c : s.toCharArray())
sum -= c;
return (char)sum;
}
}
415. 字符串相加
给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和。
注意:
num1 和num2 的长度都小于 5100.
num1 和num2 都只包含数字 0-9.
num1 和num2 都不包含任何前导零。
class Solution {
public String addStrings(String num1, String num2) {
StringBuilder sb = new StringBuilder();
int carry = 0, i = num1.length()-1, j = num2.length()-1;
while(i >= 0 || j >= 0 || carry != 0){
if(i>=0) carry += num1.charAt(i--)-'0';
if(j>=0) carry += num2.charAt(j--)-'0';
sb.append(carry%10);
carry /= 10;
}
return sb.reverse().toString();
}
}
605. 种花问题
假设你有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花卉不能种植在相邻的地块上,它们会争夺水源,两者都会死去。
给定一个花坛(表示为一个数组包含0和1,其中0表示没种植花,1表示种植了花),和一个数 n 。能否在不打破种植规则的情况下种入 n 朵花?能则返回True,不能则返回False。
示例:
输入: flowerbed = [1,0,0,0,1], n = 2
输出: False
class Solution {
public boolean canPlaceFlowers(int[] flowerbed, int n) {
int num = 0,count = 1; //假设在数组左边添加0,以解决边界问题,令count初始为1
for (int i=0;i<flowerbed.length;i++){
if (flowerbed[i] == 0)
count++;
else
count = 0;
if (count == 3){ //每连续三个0种一次花
num++;
count = 1;
}
}
if (count == 2) //如果最后count为2而不是1,表示最后一个位置可以种花
num++;
return n <= num;
}
}
443. 压缩字符串
给定一组字符,使用原地算法将其压缩。
压缩后的长度必须始终小于或等于原数组长度。
数组的每个元素应该是长度为1 的字符(不是 int 整数类型)。
在完成原地修改输入数组后,返回数组的新长度。
示例:
输入:
[“a”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”]
输出:
返回4,输入数组的前4个字符应该是:[“a”,“b”,“1”,“2”]。
说明:
由于字符"a"不重复,所以不会被压缩。"bbbbbbbbbbbb"被“b12”替代。
注意每个数字在数组中都有它自己的位置。
class Solution {
public static void main(String[] args) {
int anchor = 0, write = 0;
for (int read = 0; read < chars.length; read++) {
if (read + 1 == chars.length || chars[read + 1] != chars[read]) {
chars[write++] = chars[anchor];
if (read > anchor) { // "1,2"
for (char c: ("" + (read - anchor + 1)).toCharArray()) {
chars[write++] = c;
}
}
anchor = read + 1;
}
}
return write;
}
}
453. 最小移动次数使数组元素相等
给定一个长度为 n 的非空整数数组,找到让数组所有元素相等的最小移动次数。每次移动可以使 n - 1 个元素增加 1。
示例:
输入:
[1,2,3]
输出:
3
解释:
只需要3次移动(注意每次移动会增加两个元素的值):
[1,2,3] => [2,3,3] => [3,4,3] => [4,4,4]
public class Solution {
public int minMoves(int[] nums) {
Arrays.sort(nums);
int moves = 0;
for (int i = 1; i < nums.length; i++) {
int diff = (moves + nums[i]) - nums[i - 1];
nums[i] += moves;
moves += diff;
}
return moves;
}
}
public class Solution {
public int minMoves(int[] nums) {
int sum = 0, min = Integer.MAX_VALUE;
for (int i = 0; i < nums.length; i++) {
sum += nums[i];
min = Math.min(min, nums[i]);
}
return sum - min * nums.length;
}
}
459. 重复的子字符串
给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母,并且长度不超过10000。
示例:
输入: “abcabcabcabc”
输出: True
解释: 可由子字符串 “abc” 重复四次构成。 (或者子字符串 “abcabc” 重复两次构成。)
class Solution {
public boolean repeatedSubstringPattern(String s) {
String str = s + s;
return str.substring(1, str.length() - 1).contains(s);
}
}
class Solution {
public boolean repeatedSubstringPattern(String s) {
int len = s.length();
if (len < 2)
return false;
int mid = len / 2;
boolean flag;
for (int i = mid; i >= 1; i--) {
if (len % i == 0) {
String subs = s.substring(0, i);
flag = true;
for (int j = len / i; j > 1; j--) {
if (!subs.equals(s.substring(i * (j - 1), i * j))) {
flag = false;
break;
}
}
if (flag) return true ;
}
}
return false;
}
}
475. 供暖器
示例:
输入: [1,2,3,4],[1,4]
输出: 1
解释: 在位置1, 4上有两个供暖器。我们需要将加热半径设为1,这样所有房屋就都能得到供暖。
class Solution {
public int findRadius(int[] houses, int[] heaters) {
Arrays.sort(houses);
Arrays.sort(heaters);
int radius = 0;
int i = 0;
for (int house : houses) {
while (i < heaters.length && heaters[i] < house) // right
i++;
// 会越界
// if(heaters[i] == house)
// continue;
if (i == 0)
radius = Math.max(radius, heaters[i] - house);
else if (i == heaters.length)
return Math.max(radius, houses[houses.length-1] - heaters[heaters.length-1]);
else
radius = Math.max(radius, Math.min(heaters[i] - house, house - heaters[i - 1]));
}
return radius;
}
}
492. 构造矩形
现给定一个具体的矩形页面面积,你的任务是设计一个长度为 L 和宽度为 W 且满足以下要求的矩形的页面。要求:
-
你设计的矩形页面必须等于给定的目标面积。
-
宽度 W 不应大于长度 L,换言之,要求 L >= W 。
-
长度 L 和宽度 W 之间的差距应当尽可能小。
你需要按顺序输出你设计的页面的长度 L 和宽度 W。
示例:
输入: 4
输出: [2, 2]
解释: 目标面积是 4, 所有可能的构造方案有 [1,4], [2,2], [4,1]。
但是根据要求2,[1,4] 不符合要求; 根据要求3,[2,2] 比 [4,1] 更能符合要求. 所以输出长度 L 为 2, 宽度 W 为 2。
class Solution {
public int[] constructRectangle(int area) {
int sqrt = (int)Math.sqrt(area);
while(area % sqrt != 0) sqrt--;
return new int[]{area/sqrt,sqrt};
}
}