LeetCode热题100道-Day02
- 算法的时间复杂度应该为
O(log (m+n)),所以这里应使用二分法。定义sum为nuns1和nums2的长度和,如果sum为奇数,则找sum/2+1小的元素即为中位数,为偶数,则找sum/2,sum/2+1这两个元素。分析三种边界情况,如果index1等于len1,即越界,则返回nums2的第k小元素,index2越界,返回nums1的第k小元素,k等于1时,返回nums1第一个元素和nums2第一个元素中较小数。比较nums1[k/2-1]和nums2[k/2-1]如果nums1的小,则nums1[0]至nums1[k/2-1]这些元素都不可能是第k小元素,删除掉这些元素,再修改k,k要减去之前删除的那些元素,index1也要修改,待下轮使用。nums2小的话同理。
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int len1 = nums1.length;
int len2 = nums2.length;
int sum = len1 + len2;
if (sum % 2 != 0) {
int midIndex = sum / 2 + 1;
return getKthElement(nums1, nums2, midIndex);
} else {
int midIndex_1 = sum / 2;
int midIndex_2 = sum / 2 + 1;
double a = getKthElement(nums1, nums2, midIndex_1);
double b = getKthElement(nums1, nums2, midIndex_2);
return (a + b) / 2.0;
}
}
private int getKthElement(int[] nums1, int[] nums2, int k) {
int len1 = nums1.length;
int len2 = nums2.length;
int index1 = 0;
int index2 = 0;
while (true) {
if(index1 == len1) {
return nums2[index2 + k - 1];
}
if(index2 == len2) {
return nums1[index1 + k - 1];
}
if(k == 1) {
return Math.min(nums1[index1], nums2[index2]);
}
int half = k / 2;
int newIndex1 = Math.min(index1 + half, len1) - 1;
int newIndex2 = Math.min(index2 + half, len2) - 1;
int pivot1 = nums1[newIndex1];
int pivot2 = nums2[newIndex2];
if(pivot1 <= pivot2) {
k -= (newIndex1 - index1 + 1);
index1 = newIndex1 + 1;
} else {
k -= (newIndex2 - index2 + 1);
index2 = newIndex2 + 1;
}
}
}
}
- 此题可以使用动态规划的方法来解决,确定状态转移方程:dp[i][j] = dp[i + 1][j - 1]。定义dp数组,dp[i][j] 数组的含义: 下标 i 到 j 的字串是不是回文串(i < j),初始化dp数组,max为最大回文串的长度,start最大回文串的起始位置。进行遍历,如果字串的首位不相等,那么一定不是回文串,如果首位字符相等,处理边界条件,只要 dp[i][j] == true 成立,就表示子串 s[i..j] 是回文,此时记录回文长度max和起始位置start。
class Solution {
public String longestPalindrome(String s) {
int len = s.length();
boolean[][] dp = new boolean[len][len];
for (int i = 0; i < len; i++) {
dp[i][i] = true;
}
char[] arr = s.toCharArray();
int max = 1, start = 0;
for (int j = 1; j < len; j++) {
for (int i = 0; i < len - 1 && i < j; i++) {
if (arr[i] != arr[j]) {
dp[i][j] = false;
} else {
if (j - i <= 2) {
dp[i][j] = true;
} else {
dp[i][j] = dp[i + 1][j - 1];
}
}
if (dp[i][j] && j - i + 1 > max) {
max = j - i + 1;
start = i;
}
}
}
return s.substring(start, start + max);
}
}
class Solution {
public boolean isMatch(String s, String p) {
int m = s.length() + 1;
int n = p.length() + 1;
boolean[][] dp = new boolean[m][n];
dp[0][0] = true;
for (int j = 2; j < n; j++) {
if (p.charAt(j - 1) == '*') {
dp[0][j] = dp[0][j - 2];
}
}
for (int r = 1; r < m; r++) {
int i = r - 1;
for (int c = 1; c < n; c++) {
int j = c - 1;
if (s.charAt(i) == p.charAt(j) || p.charAt(j) == '.') {
dp[r][c] = dp[r - 1][c - 1];
} else if (p.charAt(j) == '*') {
if (p.charAt(j - 1) == s.charAt(i) || p.charAt(j - 1) == '.') {
dp[r][c] = dp[r - 1][c] || dp[r][c - 2];
} else {
dp[r][c] = dp[r][c - 2];
}
} else {
dp[r][c] = false;
}
}
}
return dp[m - 1][n - 1];
}
}