当前位置:   article > 正文

每日5题Day7 - LeetCode 31 - 35

每日5题Day7 - LeetCode 31 - 35

每一步向前都是向自己的梦想更近一步,坚持不懈,勇往直前!

第一题:31. 下一个排列 - 力扣(LeetCode)

注意这道题的处理逻辑,我们应该走最右边的数i开始,向左遍历找到小于他的数j,然后交换,一定要注意交换后右边序列(j所在位置的后一位)也要满足是升序(因为刚刚已经完成升序了,每次升一点,所有子序列就要满足是最小升序,如果看文字太抽象,请用[2,3,1]这个例子自行模拟)

  1. class Solution {
  2. public void nextPermutation(int[] nums) {
  3. int n = nums.length;
  4. // 从右向左找到第一个降序的位置 i
  5. int i = n - 2;
  6. while (i >= 0 && nums[i] >= nums[i + 1]) {
  7. i--;
  8. }
  9. // 如果找到了 i,从右向左找到第一个比 nums[i] 大的数字位置 j
  10. if (i >= 0) {
  11. int j = n - 1;
  12. while (j >= 0 && nums[j] <= nums[i]) {
  13. j--;
  14. }
  15. swap(nums, i, j); // 交换 nums[i] 和 nums[j]
  16. }
  17. // 将 i 右边的数字进行反转,使得右边变为最小的排列
  18. reverse(nums, i + 1, n - 1);
  19. }
  20. // 交换数组中的两个元素
  21. private void swap(int[] nums, int i, int j) {
  22. int temp = nums[i];
  23. nums[i] = nums[j];
  24. nums[j] = temp;
  25. }
  26. // 反转数组中从 left 到 right 位置的元素
  27. private void reverse(int[] nums, int left, int right) {
  28. while (left < right) {
  29. swap(nums, left, right);
  30. left++;
  31. right--;
  32. }
  33. }
  34. }

第二题:32. 最长有效括号 - 力扣(LeetCode)

  1. class Solution {
  2. public int longestValidParentheses(String s) {
  3. // 一看到最长,要警觉,是不是可以使用dp了?
  4. // 用于记录最长有效括号子串的长度
  5. int maxans = 0;
  6. // 创建一个数组,用于记录以当前字符结尾的最长有效括号子串的长度
  7. int[] dp = new int[s.length()];
  8. for (int i = 1; i < s.length(); i++) {
  9. // 如果当前字符为右括号
  10. if (s.charAt(i) == ')') {
  11. // 如果前一个字符是左括号,形成了一对有效括号
  12. if (s.charAt(i - 1) == '(') {
  13. // 更新以当前字符结尾的最长有效括号子串的长度
  14. dp[i] = (i >= 2 ? dp[i - 2] : 0) + 2;
  15. }
  16. // 如果前一个字符是右括号,需要判断是否能与之前的部分形成有效括号子串
  17. else if (i - dp[i - 1] > 0 && s.charAt(i - dp[i - 1] - 1) == '(') {
  18. // 更新以当前字符结尾的最长有效括号子串的长度
  19. dp[i] = dp[i - 1] + ((i - dp[i - 1]) >= 2 ? dp[i - dp[i - 1] - 2] : 0) + 2;
  20. }
  21. // 更新最长有效括号子串的长度
  22. maxans = Math.max(maxans, dp[i]);
  23. }
  24. }
  25. // 返回最长有效括号子串的长度
  26. return maxans;
  27. }
  28. }

第三题:33. 搜索旋转排序数组 - 力扣(LeetCode)

  1. class Solution {
  2. public int search(int[] nums, int target) {
  3. int lo = 0, hi = nums.length - 1, mid = 0;
  4. while (lo <= hi) {
  5. mid = lo + (hi - lo) / 2;
  6. if (nums[mid] == target) {
  7. return mid;
  8. }
  9. // 先根据 nums[mid] 与 nums[lo] 的关系判断 mid 是在左段还是右段
  10. if (nums[mid] >= nums[lo]) {
  11. // 再判断 target 是在 mid 的左边还是右边,从而调整左右边界 lo 和 hi
  12. if (target >= nums[lo] && target < nums[mid]) {
  13. hi = mid - 1;
  14. } else {
  15. lo = mid + 1;
  16. }
  17. } else {
  18. if (target > nums[mid] && target <= nums[hi]) {
  19. lo = mid + 1;
  20. } else {
  21. hi = mid - 1;
  22. }
  23. }
  24. }
  25. return -1;
  26. }
  27. }

第四题:34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣(LeetCode)

  1. class Solution {
  2. public int[] searchRange(int[] nums, int target) {
  3. int left = searchLeft(nums, target);
  4. int right = searchRight(nums, target);
  5. return new int[] { left, right };
  6. }
  7. public int searchLeft(int[] nums, int target) {
  8. // 寻找元素第一次出现的地方
  9. int left = 0;
  10. int right = nums.length - 1;
  11. while (left <= right) {
  12. int mid = left + (right - left) / 2;
  13. // >= 的都要缩小 因为要找第一个元素
  14. if (nums[mid] >= target) {
  15. right = mid - 1;
  16. } else {
  17. left = mid + 1;
  18. }
  19. }
  20. // right = left - 1
  21. // 如果存在答案 right是首选
  22. if (right >= 0 && right < nums.length && nums[right] == target) {
  23. return right;
  24. }
  25. if (left >= 0 && left < nums.length && nums[left] == target) {
  26. return left;
  27. }
  28. return -1;
  29. }
  30. public int searchRight(int[] nums, int target) {
  31. // 找最后一次出现
  32. int left = 0;
  33. int right = nums.length - 1;
  34. while (left <= right) {
  35. int mid = left + (right - left) / 2;
  36. // <= 的都要更新 因为我们要找最后一个元素
  37. if (nums[mid] <= target) {
  38. left = mid + 1;
  39. } else {
  40. right = mid - 1;
  41. }
  42. }
  43. // left = right + 1
  44. // 要找最后一次出现 如果有答案 优先找left
  45. if (left >= 0 && left < nums.length && nums[left] == target) {
  46. return left;
  47. }
  48. if (right >= 0 && right <= nums.length && nums[right] == target) {
  49. return right;
  50. }
  51. return -1;
  52. }
  53. }

 第五题:35. 搜索插入位置 - 力扣(LeetCode)

  1. class Solution {
  2. public int searchInsert(int[] nums, int target) {
  3. int n = nums.length;
  4. int left = 0, right = n - 1, ans = n;
  5. while (left <= right) {
  6. int mid = ((right - left) >> 1) + left;
  7. if (target <= nums[mid]) {
  8. //记录插入位置,其实和二分查找是一样的,不过多一个记录的过程
  9. ans = mid;
  10. right = mid - 1;
  11. } else {
  12. left = mid + 1;
  13. }
  14. }
  15. return ans;
  16. }
  17. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/615454
推荐阅读
相关标签
  

闽ICP备14008679号