leetcode刷题记录day020:412和155

412、难度简单:

改进描述基于:
作者:LeetCode
链接:https://leetcode-cn.com/problems/fizz-buzz/solution/fizz-buzz-by-leetcode/

方法一:模拟法

代码步骤:
1、首先我们需要一个初始化一个空的答案列表:
List supplierNames = new List(); 不可行原因:
List是一个Interface,不能实例化一个Interface,因为interface是一个约定,表示什么样的方法应该具有我们的类。为了实例化,需要该接口的一些实现。可以使用下面的代码以及非常流行的List接口实现:
List supplierNames = new ArrayList(); 
List supplierNames = new LinkedList();
2、遍历 1…N
3、按照题目规则给答案列表赋值

class Solution {
  public List<String> fizzBuzz(int n) {

    // ans list
    List<String> ans = new ArrayList<String>();

    for (int num = 1; num <= n; num++) {
      
      boolean divisibleBy3 = (num % 3 == 0);
      boolean divisibleBy5 = (num % 5 == 0);

      if (divisibleBy3 && divisibleBy5) {
       
        ans.add("FizzBuzz");
      } else if (divisibleBy3) {
        
        ans.add("Fizz");
      } else if (divisibleBy5) {
       
        ans.add("Buzz");
      } else {
        // 注意:这里写如下代码和写 str.add(i + 1 + ""); 在时间消耗上有很大差距
        ans.add(Integer.toString(num));
      }
    }

    return ans;
  }
}
方法二:字符串连接:

这个方法不会降低渐进复杂度,但是当 FizzBuzz 的规则变得更复杂的时候,如果还是用方法一来解决这个问题的话,那将会有非常多的条件需要判断。
原理:对于 FizzBuzz 来说,运用拼接后只需要判断两个条件就可以了,而不需要像方法一中那样判断三个条件

class Solution {
  public List<String> fizzBuzz(int n) {
    // ans list
    List<String> ans = new ArrayList<String>();

    for (int num = 1; num <= n; num++) {

      boolean divisibleBy3 = (num % 3 == 0);
      boolean divisibleBy5 = (num % 5 == 0);

      String numAnsStr = "";

      if (divisibleBy3) {
        numAnsStr += "Fizz";
      }

      if (divisibleBy5) {
        numAnsStr += "Buzz";
      }
	  // 若 numAnsStr 此时为空,说明前两个 if 都没过
      if (numAnsStr.equals("")) {
        numAnsStr += Integer.toString(num);
      }
        
      ans.add(numAnsStr);
    }

    return ans;
  }
}
方法三:用散列表:

这个方法是对方法二的优化。当数字和答案的映射是定好的,那么方法二用起来也还可以。但若题目需要更自由的映射关系呢?
每个映射一个判断显然是不可行的,这样写出来的代码难以维护。
如果老板有这样一个需求,明天你把映射关系换掉或者删除一个映射关系吧。对于这种要求,那只能一个个去修改判断条件的代码。
解决措施:把映射关系放在 散列表 里面
步骤:
1、把所有的映射关系放在散列表 fizzBuzzHash 中,这个散列表形如 { 3: ‘Fizz’, 5: ‘Buzz’ }。
2、遍历 1 … N
3、对于每个数字,遍历 fizzBuzzHash 中的键,检查是否能被它整除。
4、如果这个数能被键整除,就把当前键映射的值加到到答案字符串后面去。对于散列表的每个键值对,都这样操作。
5、最后将答案字符串加入答案列表。

class Solution {
  public List<String> fizzBuzz(int n) {

    List<String> ans = new ArrayList<String>();

    // Hash map to store all fizzbuzz mappings.
    HashMap<Integer, String> fizzBizzDict =
        new HashMap<Integer, String>() {
          {
            put(3, "Fizz");
            put(5, "Buzz");
          }
        };

    for (int num = 1; num <= n; num++) {

      String numAnsStr = "";

      for (Integer key : fizzBizzDict.keySet()) {

        // If the num is divisible by key,
        // then add the corresponding string mapping to current numAnsStr
        if (num % key == 0) {
          numAnsStr += fizzBizzDict.get(key);
        }
      }

      if (numAnsStr.equals("")) {
        // Not divisible by 3 or 5, add the number
        numAnsStr += Integer.toString(num);
      }

      // Append the current answer str to the ans list
      ans.add(numAnsStr);
    }

    return ans;
  }
}

155、难度简单:

题意:我们只需设计出一个栈,然后数值的传入等都是网站在输入
要求:能在常数时间内检索到最小元素的栈
栈的特点:先进后出,新元素放入栈顶,取元素从栈顶取

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack obj = new MinStack();
 * obj.push(val);
 * obj.pop();
 * int param_3 = obj.top();
 * int param_4 = obj.getMin();
 * 官方默认代码配置如下:
 */
class MinStack {
    public MinStack() {}
    public void push(int val) {}
    public void pop() {}
    public int top() {}
    public int getMin() {}
}
方法一:辅助栈:

原理:在每个元素 a 入栈时把当前栈的最小值 m 存储起来。在这之后无论何时,如果栈顶元素是 a,我们就可以直接返回存储的最小值 m。按照该思路,我们只需要设计一个数据结构,使得每个元素 a 与其相应的最小值 m 时刻保持一一对应。因此我们可以使用一个辅助栈,与元素栈同步插入与删除,用于存储与每个元素对应的最小值。
当一个元素要入栈时,我们取当前辅助栈的栈顶存储的最小值,与当前元素比较得出最小值,将这个最小值插入辅助栈中;
当一个元素要出栈时,我们把辅助栈的栈顶元素也一并弹出;
在任意一个时刻,栈内元素的最小值就存储在辅助栈的栈顶元素中。

class MinStack {
    // 使用Deque双端队列实现栈
    // 被进行操作的栈
    Deque<Integer> xStack;   
    // 辅助栈,用于保存对应 minStack 当前 top 元素时栈的历史最小值
    Deque<Integer> minStack; 
    
	// 初始化所有栈
    public MinStack() {
        // 与ArrayList相比,LinkedList的增删操作效率更高,而查改操作效率较低。
        xStack = new LinkedList<Integer>();
        minStack = new LinkedList<Integer>();
        // 给辅助栈加入最大值
        minStack.push(Integer.MAX_VALUE);
    }
    
    public void push(int x) {
        xStack.push(x);
        // 辅助栈对当前加入值和过往最小值进行比较,选择更小值进行加入
        minStack.push(Math.min(minStack.peek(), x));
    }
    
    public void pop() {
        xStack.pop();
        minStack.pop();
    }
    
    public int top() {
        // LinkedList 的方法:返回第一个元素
        return xStack.peek();
    }
    
    public int getMin() {
        return minStack.peek();
    }
}

对上述代码中 Deque xStack = new LinkedList(); 的解释:
Java中LinkedList类实现了两者DequeList接口

若想要实现队列,选择所需的性能,存储和访问特性的接口来实现Queue,例如

  • LinkedList使用更多内存,但在清空队列时收缩。
  • ArrayDeque使用较少的内存,但它不会缩小。
  • PriorityQueue是一个具有元素优先级的非FIFO队列。
  • ConcurrentLinkedQueueConcurrentLinkedDeque支持多线程并发访问。
  • 和更多…
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CodeYello

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值