1. 两数之和
难度简单7789
给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。
示例: 给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
public class Solution {
//暴力
public int[] twoSum(int[] nums, int target) {
int[] result = new int[2]; //初始化
for(int i = 0; i < nums.length - 1; i++) {
for(int j = i + 1; j < nums.length; j++) {
if(nums[i] + nums[j] == target) {
result[0] = i;
result[1] = j;
break;
}
}
}
return result;
}
//利用哈希表
public int[] twoSum(int[] nums, int target) {
int[] result = new int[2];
Map<Integer, Integer> hashMap = new HashMap<>();
for(int i = 0; i < nums.length; i++) {
if(hashMap.containsKey(nums[i])) {
result[0] = hashMap.get(nums[i]);
result[1] = i;
}
//利用存储的数组是按照升序排列的特点
hashMap.put(target-nums[i], i); //存储差值
}
return result;
}
}
2. 两个排序数组中的中位数
给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 。请找出这两个有序数组的中位数。要求算法的时间复杂度为 O(log(m+n))。你可以假设 nums1 和 nums2 不同时为空。
示例 1: nums1 = [1, 3] nums2 = [2] 中位数是 2.0
示例 2: nums1 = [1, 2] nums2 = [3, 4] 中位数是 (2 + 3)/2 = 2.5
public class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
//暴力
// double result = 0;
// int length = nums1.length + nums2.length;
// int[] nums = new int[length];
// int j = 0, k = 0;
// for(int i = 0; i<length; i++) {
// if(j < nums1.length) {
// nums[i] = nums1[j];
// j++;
// continue;
// }
// if(k < nums2.length) {
// nums[i] = nums2[k];
// k++;
// continue;
// }
// }
// for(int i = 0; i<length-1; i++) {
// for(int l = i+1; l<length; l++) {
// if(nums[l] < nums[i]) {
// int a = nums[l];
// nums[l] = nums[i];
// nums[i] = a;
// }
// }
// }
// if(length%2 == 0) {
// int mid = length / 2 - 1;
// double num1 = nums[mid];
// double num2 = nums[mid+1];
// result = (num1 + num2) / 2;
// } else {
// int mid = (length - 1) / 2;
// result = nums[mid];
// }
// return result;
//开一个新数组,存入数组之前进行排序
int m = nums1.length;
int n = nums2.length;
int len = m + n;
int[] result = new int[m + n];
int i = 0, j = 0, k = 0;
while (m != 0 && n != 0) {
if (nums1[j] < nums2[k]) {
result[i] = nums1[j];
i++;
j++;
m--;
} else {
result[i] = nums2[k];
i++;
k++;
n--;
}
}
if (m == 0) {
while (i < len) {
result[i] = nums2[k];
i++;
k++;
}
}
if (n == 0) {
while (i < len) {
result[i] = nums1[j];
i++;
j++;
}
}
if (len % 2 == 0) {
int mid = len / 2 - 1;
double num1 = result[mid];
double num2 = result[mid + 1];
return (num1 + num2) / 2;
} else {
int mid = (len - 1) / 2;
return result[mid];
}
}
}
3. 最长回文子串
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为1000。
示例 1:输入: "babad" 输出: "bab" 注意: "aba"也是一个有效答案。
示例 2:输入: "cbbd" 输出: "bb"
public class Solution {
//暴力
public String longestPalindrome(String s) {
int maxLen = 0;
int maxStart = 0;
int length = s.length();
for(int i = 0; i<length; i++) { //字符串长度
for(int j = 0; j<length-i; j++) { //字符串起始位置
if(isPalindrome(s, j ,i) && (i+1)>maxLen) {
maxLen = i + 1; //加上起始位
maxStart = j;
}
}
}
return s.substring(maxStart, maxStart+maxLen);
}
/*
动态规划
先建立一个二维数组dp,
令dp[i][j]表示s[i...j] = 1是回文字符串,用其等于0则表示不是回文子串
如果s.charAt(i)==s.charAt(j)并且dp[i+1][j-1]是true
则dp[i][j]也为true
*/
public String longestPalindrome(String s) {
if (s.length() <= 1)
return s;
String longest = s.charAt(0)+"";
int length = s.length();
boolean[][] dp = new boolean[length][length];
for(int j = length-1; j>=0; j--){
//j在前,i在后
for(int i = j; i<length; i++){
dp[j][i] = s.charAt(i)==s.charAt(j) && ((i-j<3)||dp[j+1][i-1]);
if(dp[j][i] && (i-j+1)>longest.length()){
longest = s.substring(j,i+1);
}
}
}
return longest;
}
public boolean isPalindrome(String str, int start, int len) {
int left = start;
int right = start + len;
while(left == right) {
if(str.charAt(left) != str.charAt(right)) {
return false;
}
left++;
right--;
}
return true;
}
}
4. 字符串转整数(atoi)
请你来实现一个 atoi 函数,使其能将字符串转换成整数。
首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。
当我们寻找到的第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字组合起来,作为该整数的正负号;假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成整数。该字符串除了有效的整数部分之后也可能会存在多余的字符,这些字符可以被忽略,它们对于函数不应该造成影响。
注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换。
在任何情况下,若函数不能进行有效的转换时,请返回 0。
说明:假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231, 231 − 1]。
如果数值超过可表示的范围,则返回 INT_MAX (231 − 1) 或 INT_MIN (−231)。
public class Solution {
/*
思路:
按照函数说明来一步步处理。首先判断输入是否为null。
然后使用trim()函数删掉空格。判断是否有正负号,做一个标记。
返回的是整形数,可以使用double来暂存结果。按位来计算出结果。
如果遇到非数字字符,则返回当前结果。加上前面的正负号。
结果若超出了整形范围,则返回最大或最小值。最后返回处理结果。
*/
public int myAtoi(String str) {
if (str == null || str.length() < 1 || str.trim().isEmpty()) {
return 0;
}
str = str.trim(); // kill add white spaces
int i = 0; // index of str
char flag = '+'; // default positive
if (str.charAt(0) == '-') {
flag = '-';
i++;
} else if (str.charAt(0) == '+') {
i++;
}
double res = 0;
// abandon the non-digit char; calculate the result
while (str.length() > i && str.charAt(i) >= '0' && str.charAt(i) <= '9') {
res = res * 10 + str.charAt(i) - '0';
i++;
}
if (flag == '-') res = -1 * res;
if (res > Integer.MAX_VALUE) {
return Integer.MAX_VALUE;
} else if (res < Integer.MIN_VALUE) {
return Integer.MIN_VALUE;
}
return (int) res;
}