LeetCode刷题笔记(二)

﹏ヽ暗。殇╰゛Y 2023-06-21 04:56 181阅读 0赞

6. 字符串转换整数

请你来实现一个 atoi 函数,使其能将字符串转换成整数。

首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。

当我们寻找到的第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字组合起来,作为该整数的正负号;假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成整数。

该字符串除了有效的整数部分之后也可能会存在多余的字符,这些字符可以被忽略,它们对于函数不应该造成影响。

注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换。

在任何情况下,若函数不能进行有效的转换时,请返回 0。

说明:

假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−2^31, 2^31 − 1]。如果数值超过这个范围,请返回 INT_MAX (2^31 − 1) 或 INT_MIN (−2^31) 。

示例 1:

输入: “42”
输出: 42

示例 2:

输入: “ -42”
输出: -42
解释: 第一个非空白字符为 ‘-‘, 它是一个负号。我们尽可能将负号与后面所有连续出现的数字组合起来,最后得到 -42 。

示例 3:

输入: “4193 with words”
输出: 4193
解释: 转换截止于数字 ‘3’ ,因为它的下一个字符不为数字。

示例 4:

输入: “words and 987”
输出: 0
解释: 第一个非空字符是 ‘w’, 但它不是数字或正、负号。因此无法执行有效的转换。

示例 5:

输入: “-91283472332”
输出: -2147483648
解释: 数字 “-91283472332” 超过 32 位有符号整数范围。
因此返回 INT_MIN (−2^31) 。

解法一,使用正则:

  1. //需要导入包
  2. import java.util.regex.*;
  3. class Solution {
  4. public int myAtoi(String str) {
  5. //清空字符串开头和末尾空格(这是trim方法功能,事实上我们只需清空开头空格)
  6. str = str.trim();
  7. // 构建正则表达式
  8. Pattern p = Pattern.compile("^[\\+\\-]?\\d+");
  9. Matcher m = p.matcher(str);
  10. int value = 0;
  11. //判断是否能匹配
  12. if (m.find()){
  13. String numStr = m.group(0);
  14. try {
  15. value = Integer.parseInt(numStr);
  16. } catch (Exception e){
  17. //由于有的字符串"42"没有正号,所以我们判断'-'
  18. value = numStr.charAt(0) == '-' ? Integer.MIN_VALUE: Integer.MAX_VALUE;
  19. }
  20. }
  21. return value;
  22. }
  23. }

解法二:

  1. class Solution {
  2. public int myAtoi(String str) {
  3. //清空字符串开头和末尾空格(这是trim方法功能,事实上我们只需清空开头空格)
  4. str = str.trim();
  5. if(str.length()==0){
  6. return 0;
  7. }
  8. StringBuilder sb = new StringBuilder();
  9. char[] chars = str.toCharArray();
  10. if(chars[0] >= '0' && chars[0] <= '9'){
  11. for(char c:chars){
  12. if(c >= '0' && c <= '9'){
  13. sb.append(c);
  14. }else{
  15. break;
  16. }
  17. }
  18. }else if((chars[0] == '+' || chars[0] == '-') && chars.length>1){
  19. if(chars[1] >= '0' && chars[1] <= '9'){
  20. sb.append(chars[0]);
  21. sb.append(chars[1]);
  22. for(int i = 2;i<chars.length;i++){
  23. if(chars[i] >= '0' && chars[i] <= '9'){
  24. sb.append(chars[i]);
  25. }else{
  26. break;
  27. }
  28. }
  29. }else{
  30. return 0;
  31. }
  32. }else{
  33. return 0;
  34. }
  35. int value = 0;
  36. try {
  37. value = Integer.parseInt(sb.toString());
  38. } catch (Exception e){
  39. //由于有的字符串"42"没有正号,所以我们判断'-'
  40. value = sb.toString().charAt(0) == '-' ? Integer.MIN_VALUE: Integer.MAX_VALUE;
  41. }
  42. return value;
  43. }
  44. }

7. 回文数

判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。

示例 1:

输入: 121
输出: true

示例 2:

输入: -121
输出: false
解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。

示例 3:

输入: 10
输出: false
解释: 从右向左读, 为 01 。因此它不是一个回文数。

解法一,将数字转为字符串:

  1. class Solution {
  2. public boolean isPalindrome(int x) {
  3. if(x < 0){
  4. return false;
  5. }
  6. String str1 = x+"";
  7. StringBuilder sb = new StringBuilder(str1);
  8. String str2 = sb.reverse().toString();
  9. return str1.equals(str2);
  10. }
  11. }

进阶:你能不将整数转为字符串来解决这个问题吗?

  1. class Solution {
  2. public boolean isPalindrome(int x) {
  3. // 负数和能被十整除的不是回文数
  4. if(x < 0 || ( x % 10 == 0 && x!= 0)){
  5. return false;
  6. }
  7. int tmp = x;
  8. int len = 0;
  9. // 获取数字的长度
  10. while(tmp>0){
  11. tmp = tmp / 10;
  12. len ++;
  13. }
  14. // 取一半长度,奇数长度忽略中位数
  15. int count = len / 2;
  16. int dev = 1;
  17. for(int i = 0;i< count;i++){
  18. dev *=10;
  19. }
  20. // 取又半部分数字
  21. int right_half = x % dev;
  22. // 左半部分数字反转
  23. int left_half = len % 2 == 0 ? x/ dev: x/ (dev*10);
  24. int left_reverse = 0;
  25. while(left_half>0){
  26. int m = left_half % 10;
  27. left_half = left_half /10;
  28. left_reverse = left_reverse * 10 + m;
  29. }
  30. return left_reverse == right_half;
  31. }
  32. }

8. 盛最多水的容器

给定 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

说明:你不能倾斜容器,且 n 的值至少为 2。

图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3BlbmdqdW5sZWU_size_16_color_FFFFFF_t_70

示例:

输入: [1,8,6,2,5,4,8,3,7]
输出: 49

解法一,暴力穷尽:

  1. class Solution {
  2. public int maxArea(int[] height) {
  3. int maxArea = 0;
  4. for(int i=0;i<height.length-1;i++ ){
  5. for(int j = i +1;j<height.length;j++){
  6. int area = (j-i)*Math.min(height[i],height[j]);
  7. if(maxArea < area){
  8. maxArea = area;
  9. }
  10. }
  11. }
  12. return maxArea;
  13. }
  14. }

方法二,双向指针:

20191211153210863.png

  1. class Solution {
  2. public int maxArea(int[] height) {
  3. int maxArea = 0;
  4. int len = height.length;
  5. for(int i=0;i<len-1;i++ ){
  6. for(int j = len -1;j>i;j--){
  7. if(height[j]>=height[i]){
  8. maxArea = Math.max(maxArea,height[i]*(j-i));
  9. break;
  10. }else{
  11. maxArea = Math.max(maxArea,height[j]*(j-i));
  12. }
  13. }
  14. }
  15. return maxArea;
  16. }
  17. }

9. 最长公共前缀

编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 “”。

示例 1:

输入: [“flower”,”flow”,”flight”]
输出: “fl”

示例 2:

输入: [“dog”,”racecar”,”car”]
输出: “”
解释: 输入不存在公共前缀。

说明:所有输入只包含小写字母 a-z 。

解法:

  1. class Solution {
  2. public String longestCommonPrefix(String[] strs) {
  3. String prefix = null;
  4. for(String str : strs){
  5. if(prefix == null){
  6. prefix = str;
  7. }else if(prefix.length()>str.length()){
  8. prefix = str;
  9. }
  10. }
  11. if(prefix == null || prefix.equals("")){
  12. return "";
  13. }
  14. int index = prefix.length();
  15. for(String str:strs){
  16. if(!str.equals(prefix)){
  17. for(int i = 0 ;i<index;i++){
  18. if(str.charAt(i) != prefix.charAt(i)){
  19. index = i;
  20. break;
  21. }
  22. }
  23. }
  24. }
  25. return prefix.substring(0,index);
  26. }
  27. }

10. 删除链表的倒数第N个节点

给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。

示例:

给定一个链表: 1->2->3->4->5, 和 n = 2.

当删除了倒数第二个节点后,链表变为 1->2->3->5.

说明:给定的 n 保证是有效的。

进阶:你能尝试使用一趟扫描实现吗?

20191211173426726.gif

  1. /**
  2. * Definition for singly-linked list.
  3. * public class ListNode {
  4. * int val;
  5. * ListNode next;
  6. * ListNode(int x) { val = x; }
  7. * }
  8. */
  9. class Solution {
  10. public ListNode removeNthFromEnd(ListNode head, int n) {
  11. if(head.next == null){
  12. return null;
  13. }
  14. ListNode node = head;
  15. ListNode beforeNode = null;
  16. while(node!=null){
  17. if(n == 0){
  18. beforeNode = beforeNode == null? head: beforeNode.next;
  19. }else{
  20. n-- ;
  21. }
  22. node = node.next;
  23. }
  24. if(null==beforeNode){
  25. head = head.next;
  26. }else{
  27. beforeNode.next = beforeNode.next.next;
  28. }
  29. return head;
  30. }
  31. }

发表评论

表情:
评论列表 (有 0 条评论,181人围观)

还没有评论,来说两句吧...

相关阅读

    相关 LeetCode笔记

    [23. Merge k Sorted Lists][] > 要点: > > 1. 学会数据结构PriorityQueue(优先队列)的用法, 通过给优先队列传入自定义