3.leetcode简单算法题

文章目录

  • 整数反转
    • 题干
    • 我的思路与代码
    • 解析
    • 踩坑与收获
  • 回文数
    • 题干
    • 我的思路与代码
    • 解析
    • 总结与收获
  • 罗马数字转整数
    • 题干
    • 我的思路
    • 解析
  • 最长公共前缀
    • 题干
    • 我的思路与代码
    • 解析
  • 有效的括号
    • 题干
    • 我的思路与代码
    • 解析

整数反转

题干

给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231, 231 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。

我的思路与代码

class Solution {
    public int reverse(int x) {
        //拿到几位数n,然后拿出来一个尾巴,跟n计算一下。
        //需要考虑正负,最后一位是0
        
        //处理正负
        boolean isLowerThanZero = false;
        if (x<0) {
            isLowerThanZero = true;
            x = -x;
        } 
        //用栈来存放数据
        Stack stack = new Stack();
        while(x != 0){
           stack.push(x%10);
           x = x/10;
        }
		//下面这段代码是从栈里拿出来数据组装成想要的样子 123 -》 321
        int result = 0;
        int tenTimes = 1;
        while(!stack.empty()){
            result = result + (int)stack.pop()*tenTimes;
            tenTimes *= 10;
        }
        //考虑整数溢出的情况,这部分代码有问题一直没调出来
        int max = (2<<31) -1 ;
        if(result > 2147483647){
            return 0;
        }
        //如果是负数还原
        if(isLowerThanZero){
            result = -result;
        }
        return result;
    }
}

废了很多功夫,最终没做出来。指数运算与溢出的处理,超出了脑容量了。处理的不是很好。做的过程中很努力的在避开循环了,但是还是做的不好。

解析

3.leetcode简单算法题_第1张图片

class Solution {
    public int reverse(int x) {
        int rev = 0;
        while (x != 0) {
            int pop = x % 10;
            x /= 10;
            if (rev > Integer.MAX_VALUE/10 || (rev == Integer.MAX_VALUE / 10 && pop > 7)) return 0;
            if (rev < Integer.MIN_VALUE/10 || (rev == Integer.MIN_VALUE / 10 && pop < -8)) return 0;
            rev = rev * 10 + pop;
        }
        return rev;
    }
}

3.leetcode简单算法题_第2张图片

踩坑与收获

  1. if条件判断,遇到多个与或的情况,要用括号明确的标示出优先级。要不就容易不按照预想的进行。
  2. int的max与min,已经在Integer对象中定义出来了,不用自己用2去移位了。

回文数

题干

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

我的思路与代码

回文数无非就是头尾对应位置的数是一样的,就想着转化为字符串去匹配。
过程中需要注意,字符串最后一个是str.length()-1。跟数组一样,到不了length,是从0开始的。

class Solution {
    public boolean isPalindrome(int x) {
      //转换成字符串
        String str = x + "";
        boolean result = true;
        for (int i = 0; i < str.length()/2; i++) {
            if(str.charAt(i) != str.charAt(str.length()-1-i)){
                result = false;
            }
        }
        return result;
    }
}

解析

3.leetcode简单算法题_第3张图片

public class Solution {
    public bool IsPalindrome(int x) {
        // 特殊情况:
        // 如上所述,当 x < 0 时,x 不是回文数。
        // 同样地,如果数字的最后一位是 0,为了使该数字为回文,
        // 则其第一位数字也应该是 0
        // 只有 0 满足这一属性
        if(x < 0 || (x % 10 == 0 && x != 0)) {
            return false;
        }

        int revertedNumber = 0;
        while(x > revertedNumber) {
            revertedNumber = revertedNumber * 10 + x % 10;
            x /= 10;
        }

        // 当数字长度为奇数时,我们可以通过 revertedNumber/10 去除处于中位的数字。
        // 例如,当输入为 12321 时,在 while 循环的末尾我们可以得到 x = 12,revertedNumber = 123,
        // 由于处于中位的数字不影响回文(它总是与自己相等),所以我们可以简单地将其去除。
        return x == revertedNumber || x == revertedNumber/10;
    }
}

 

在这里插入图片描述

总结与收获

  1. 时空复杂度的计算需要强化一下。
  2. 如何截取一半的数字? 一边截取一边跟截断之后的原串比一下。

罗马数字转整数

题干

3.leetcode简单算法题_第4张图片

我的思路

先建立一个罗马数字与数值对应的字典,然后一个一个字符解析之后累加。
针对特殊处理的字符,确定之后,用负数的形式进行特殊的负数累加。
我认为这个思路没什么问题,但是sign那一行报空指针。最后原因是我初始化字典的时候,错用了双引号。
最终也可以成功提交。

   // 先把字典装进map里面
        Map<Character,Integer> map = new HashMap<>();
        //1
       map.put('I',1);
        map.put('V',5);
        map.put('X',10);
        map.put('L',50);
        map.put('C',100);
        map.put('D',500);
        map.put('M',1000);
        // 符号
        int result = 0;
        for (int i = 0; i < s.length()-1; i++) {
            int sign = 1;
            if ((s.charAt(i)=='I' ||s.charAt(i)=='X' ||s.charAt(i)=='C')  ) {  
                if(map.get(s.charAt(i))*5 ==map.get(s.charAt(i+1)) ||
                   map.get(s.charAt(i))*10 ==map.get(s.charAt(i+1))){
                    sign = -1;
                }
            }
            result+= sign* map.get(s.charAt(i));
        }
        result+= map.get(s.charAt(s.length()-1));
        return  result;
        
    }

解析

3.leetcode简单算法题_第5张图片
代码:

class Solution {
    public int romanToInt(String s) {
        Map<String, Integer> map = new HashMap<>();
        map.put("I", 1);
        map.put("IV", 4);
        map.put("V", 5);
        map.put("IX", 9);
        map.put("X", 10);
        map.put("XL", 40);
        map.put("L", 50);
        map.put("XC", 90);
        map.put("C", 100);
        map.put("CD", 400);
        map.put("D", 500);
        map.put("CM", 900);
        map.put("M", 1000);
        
        int ans = 0;
        for(int i = 0;i < s.length();) {
            if(i + 1 < s.length() && map.containsKey(s.substring(i, i+2))) {
                ans += map.get(s.substring(i, i+2));
                i += 2;
            } else {
                ans += map.get(s.substring(i, i+1));
                i ++;
            }
        }
        return ans;
    }
}

解析里面的做法是在哈希表里面增加一个字符与2个字符。然后利用字符串切割并匹配的思路。
根据用的字符的数量移动游标i,控制一步还是两步。
这个解法比我想的要更奇妙。
hashmap可以换成switch,可能效率更快。

最长公共前缀

题干

3.leetcode简单算法题_第6张图片

我的思路与代码

class Solution {
    public String longestCommonPrefix(String[] strs) {

        if(strs.length == 0){
            return "";
        }
        //1.比较长度 选最小的长度 作为循环的n   拿出来去比
        int minLengthIndex = 0;
        for (int i = 1; i < strs.length; i++) {
            if (strs[i].length()< strs[minLengthIndex].length()) {
                minLengthIndex = i;
            }
        }
        String CommonPrefix = ""; 
        for (int i = 0; i < strs[minLengthIndex].length() ; i ++) {
            boolean isAdd = true;
            for (int j = 0; j < strs.length; j++) {
                if (strs[j].charAt(i)!=strs[minLengthIndex].charAt(i)) {
                    isAdd = false;
                    break;
                }  
            }
            if(isAdd){ 
                CommonPrefix = CommonPrefix + strs[minLengthIndex].charAt(i);
                }else {
 				break;
			}
           
        }
        return CommonPrefix;

    }
}

上来判断一下特殊情况,空数组。
然后找出最短长度的数组中的元素,作为字符游标移动的母串。
以最短的那个为目标,对比每一个的每一位,看是不是一样。
思路很简单,但是部分测试用例。没有通过。
后来ide打断点,我对后面匹配的数据没有做处理,加了isAdd的else判断之后就能通过了。
3.leetcode简单算法题_第7张图片

解析

这个题,解析有好多。

有效的括号

题干

给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。

我的思路与代码

首先想到的就是栈的思想,加一个哈希表做检索匹配。但是代码最终失败了。

class Solution {
    public boolean isValid(String s) {
       //第一想到的就是栈
        Stack stack = new Stack();
        boolean result = true;
        Map<String,String> map = new HashMap<>();
        map.put(")","(");
        map.put("}","{");
        map.put("]","[");
        while(s.equals("")){
            Character tmp = s.charAt(0);
            if (map.containsKey(tmp+"")) {
                String returnChar = (String)stack.pop();
                if (!returnChar.equals(map.get(tmp+""))) {
                    result = false;
                }
            }else{
                stack.push(tmp+"");
            }
          
            s = s.substring(1);
            
        }
        if(!stack.empty()){
            result = false;
        } 
        return result;
    }
}

解析

总的来说,我用栈这种数据结构的思想是对的。
跟我的实现方式也差不多。但是我的代码为啥有问题,一直没发现。

class Solution {

  // Hash table that takes care of the mappings.
  private HashMap<Character, Character> mappings;

  // Initialize hash map with mappings. This simply makes the code easier to read.
  public Solution() {
    this.mappings = new HashMap<Character, Character>();
    this.mappings.put(')', '(');
    this.mappings.put('}', '{');
    this.mappings.put(']', '[');
  }

  public boolean isValid(String s) {

    // Initialize a stack to be used in the algorithm.
    Stack<Character> stack = new Stack<Character>();

    for (int i = 0; i < s.length(); i++) {
      char c = s.charAt(i);

      // If the current character is a closing bracket.
      if (this.mappings.containsKey(c)) {

        // Get the top element of the stack. If the stack is empty, set a dummy value of '#'
        char topElement = stack.empty() ? '#' : stack.pop();

        // If the mapping for this bracket doesn't match the stack's top element, return false.
        if (topElement != this.mappings.get(c)) {
          return false;
        }
      } else {
        // If it was an opening bracket, push to the stack.
        stack.push(c);
      }
    }

    // If the stack still contains elements, then it is an invalid expression.
    return stack.isEmpty();
  }
}

到这里,我不再强刷算法了,回过头了,重新看一遍java的数据结构,对东西建立起来体系再回来!

你可能感兴趣的:(leetcode)