第一题
思路:贪心 + 滑动窗口
public class 第一题03 {
public static int maxPairNum(int[] arr,int k){
if (k < 0 || arr == null || arr.length <= 1){
return 0;
}
Arrays.sort(arr);
int n = arr.length;
int l = 0;
int r = 0;
boolean[] visit = new boolean[n];
int ans = 0;
while (r < n){
if (visit[l]){
l++;
}else if (l == r){
r++;
}else {
if (arr[r] - arr[l] == k){
ans++;
visit[r] = true;
l++;
r++;
}else if (arr[r] - arr[l] > k){
l++;
}else {
r++;
}
}
}
return ans;
}
public static void main(String[] args) {
int[] arr = {1,1,2,4,6,8,6,9,3,3,5,7};
int res = maxPairNum(arr, 2);
System.out.println(res);
}
}
第二题
public class 第二题03 {
public static int minBoot(int[] arr,int limit){
if (arr == null || arr.length < 1){
return 0;
}
int N = arr.length;
Arrays.sort(arr);
if (arr[N - 1] > limit){
return -1;
}
int half_limit = limit / 2;
int last_L = 0;
int last_R = 0;
for (int i = 0;i < N;i++){
if (arr[i] > half_limit){
last_L = i - 1;
last_R = i;
break;
}
}
int ans = 0;
int num_x = 0;
while (last_L >= 0 && last_R < N){
int sum = arr[last_L] + arr[last_R];
if (sum > limit){
last_L--;
num_x++;
}else if (sum <= limit){
last_R++;
last_L--;
ans++;
}
}
int res = ans + (num_x + 1) / 2 + (N - last_R);
return res;
}
public static void main(String[] args) {
int[] arr = {1,1,1,1,2,3,5,5,5,5,6,6,7,8,9,10};
int res = minBoot(arr, 10);
System.out.println(res);
}
}
第三题
public class 第三题03 {
public static int maxSum(int[] arr){
if (arr == null || arr.length < 1){
return 0;
}
int n = arr.length;
int max = arr[0];
int sum = 0;
for (int i = 0;i < n;i++){
if (sum < 0){
sum = arr[i];
}else {
sum += arr[i];
}
max = Math.max(max,sum);
}
return max;
}
public static void main(String[] args) {
int[] arr = {-3,4,-3,2,-1,1,6,-7};
int res = maxSum(arr);
System.out.println(res);
}
}
第四题
leetcode135:分发糖果
进阶问题:
n个人参加比赛,结束后每个人一个分数。
领奖时所有人依次排成一圈,第一个和第n个相邻。
要求:
1.如果某个人的分数比旁边的人高,那么奖品数量也要比他多。
2.每个至少得一个奖品。
问最少应该准备多少个奖品?
进阶问题思路:化圈为直,找到数组中小于左右两边的数开始遍历,后面步骤同leetcode135
public class 第四题03 {
//leetcode135:分发糖果
public static int candy(int[] ratings){
int n = ratings.length;
int[] left_candy = new int[n];
int[] right_candy = new int[n];
Arrays.fill(left_candy,1);
Arrays.fill(right_candy,1);
for (int i = 1;i < n;i++){
if (ratings[i] > ratings[i - 1]){
left_candy[i] = left_candy[i - 1] + 1;
}
}
for (int i = n - 2;i >= 0;i--){
if (ratings[i] > ratings[i + 1]){
right_candy[i] = right_candy[i + 1] + 1;
}
}
int sum = 0;
for (int i = 0;i < n;i++){
sum += Math.max(left_candy[i],right_candy[i]);
}
return sum;
}
//进阶问题:小朋友做一圈,进行分发糖果,规则同上
public static int candy_advance(int[] ratings){
int n = ratings.length;
int min_index = 0;
for (int i = 0;i < n;i++){
if (i == 0){
if (ratings[i] <= ratings[n - 1] && ratings[i] <= ratings[i + 1]){
min_index = i;
break;
}
}else if (i == n - 1){
if (ratings[i] <= ratings[0] && ratings[i] <= ratings[i - 1]){
min_index = i;
break;
}
}else {
if (ratings[i] <= ratings[i + 1] && ratings[i] <= ratings[i - 1]){
min_index = i;
break;
}
}
}
int[] newRatings = new int[n + 1];
System.arraycopy(ratings,min_index,newRatings,0,n - min_index);
System.arraycopy(ratings,0,newRatings,n - min_index,min_index);
newRatings[n] = ratings[min_index];
int[] left_candy = new int[n];
int[] right_candy = new int[n];
Arrays.fill(left_candy,1);
Arrays.fill(right_candy,1);
for (int i = 1;i < n;i++){
if (newRatings[i] > newRatings[i - 1]){
left_candy[i] = newRatings[i - 1] + 1;
}
}
for (int i = n - 2;i >= 0;i--){
if (newRatings[i] > newRatings[i + 1]){
right_candy[i] = right_candy[i + 1] + 1;
}
}
int sum = 0;
for (int i = 0;i < n;i++){
sum += Math.max(left_candy[i],right_candy[i]);
}
return sum - 1;
}
public static void main(String[] args) {
int[] ratings = {4,3,1,2,1,3};
int res = candy_advance(ratings);
System.out.println(res);
}
}
第五题
leetcode97:交错字符串
思路:动态规划(类似路径查找)
public class 第五题03 {
public static boolean isInterleave(String s1, String s2, String s3) {
if (s3.length() > s1.length() + s2.length()){
return false;
}
int n = s1.length();
int m = s2.length();
int k = s3.length();
boolean[][] dp = new boolean[n + 1][m + 1];
dp[0][0] = true;
for (int i = 1;i < n && s1.charAt(i - 1) == s3.charAt(i - 1);i++){
dp[i][0]= true;
}
for (int i = 1;i < m && s2.charAt(i - 1) == s3.charAt(i - 1);i++){
dp[0][i] = true;
}
for (int i = 1;i <= n;i++){
for (int j = 1;j <= m;j++){
dp[i][j] = (dp[i - 1][j] && s1.charAt(i - 1) == s3.charAt(i + j - 1)
|| (dp[i][j - 1] && s2.charAt(j - 1) == s3.charAt(i + j - 1)));
}
}
return dp[n][m];
}
}
第六题
思路:递归:sum = 左边子树相等的数量 + 右边子树相等的数量 + 中间的左右子树是否相等 ?1 :0;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
public class 第六题03 {
public static int sameNumber(TreeNode head){
if (head == null){
return 0;
}
return sameNumber(head.left) + sameNumber(head.right) + (same(head.left,head.right) ? 1 : 0);
}
private static boolean same(TreeNode left, TreeNode right) {
if (left == null && right == null){
return true;
}
//判断一个为空,另一个不为空
// if ((left == null && right != null) || left != null && right == null){
// return false;
// }
if (left == null ^ right == null){//同上代码作用一样:判断一个为空,另一个不为空
return false;
}
return left.val == right.val && same(left.left,right.left) && same(left.right,right.right);
}
}
第七题
leetcode72
public static int minDistance(String word1, String word2) {
int n = word1.length();
int m = word2.length();
int[][] dp = new int[m + 1][n + 1];
for (int i = 0;i <= m;i++){
dp[i][0] = i;
}
for (int i = 0;i <= n;i++){
dp[0][i] = i;
}
for (int i = 1;i <= m;i++){
for (int j = 1;j <= n;j++){
if (word1.charAt(j - 1) == word2.charAt(i - 1)){
dp[i][j] = dp[i - 1][j - 1];
}else {
dp[i][j] = Math.min(dp[i - 1][j - 1],Math.min(dp[i - 1][j],dp[i][j - 1])) + 1;
}
}
}
return dp[m][n];
}