每日一练(day09补08,03,04)

Posted 'or 1 or 不正经の泡泡

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每日一练(day09补08,03,04)相关的知识,希望对你有一定的参考价值。

文章目录

前言

最近繁琐的事情比较多,所以没有连续学习(好吧我也懒,没有在当天补回来,所以今天还是来一点简单题吧,所以今天的题目可能比较水,基本上没有难度)

题目

day09

最大子数组和(经典)

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

子数组 是数组中的一个连续部分。

示例 1:

输入:nums = [-2,1,-3,4,-1,2,1,-5,4] 输出:6 解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。
示例 2:

输入:nums = [1] 输出:1 示例 3:

输入:nums = [5,4,-1,7,8] 输出:23

这个题目第一个最先想到的就是暴力求解嘛 N的平方复杂度。
找出所有子串,然后返回最大值,但是这样的复杂度不管是时间还是空间,那个都不低。所以这里使用 Dp 思想去做。

那么为什么这里可以使用这个dp的思想呢,其实也很好解释。我们可以取个巧,首先我们还是老样子我们需要得到子数组,但是这个子数组有个特点,那就是这些数组里面一定有以当前数字作为子数组右边界的数组,并且我门字需要求最大值,当前为右边界为最大的值的子数组之间进行比较,还是举个例子吧。

现在状态方程都给出来了,那不就简单了。

class Solution 
    public int maxSubArray(int[] nums) 
        int pre = 0, maxAns = nums[0];
        for (int x : nums) 
            pre = Math.max(pre + x, x);
            maxAns = Math.max(maxAns, pre);
        
        return maxAns;
    


加一

给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。

最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。

你可以假设除了整数 0 之外,这个整数不会以零开头。

示例 1:

输入:digits = [1,2,3] 输出:[1,2,4] 解释:输入数组表示数字 123。

class Solution 
    public int[] plusOne(int[] digits) 
        for (int i = digits.length - 1; i >= 0; i--) 
            digits[i]++;
            digits[i] = digits[i] % 10;
            if (digits[i] != 0) return digits;
        
        digits = new int[digits.length + 1];
        digits[0] = 1;
        return digits;
    


这个没啥好说的,直接上。

二进制求和

题目就不给了,就是叫你写一个二级制加法器。

输入: a = “11”, b = “1” 输出: “100”

这里注意输入的是字符串。

第一个方法直接偷懒。

class Solution 
    public String addBinary(String a, String b) 
        return Integer.toBinaryString(
            Integer.parseInt(a, 2) + Integer.parseInt(b, 2)
        );
    


第二个方法其实和我们先前做的两数相加是一样的,只不过现在换成了字符串,然后没有逆序,没有对位补0.

class Solution 
    public String addBinary(String a, String b) 
        StringBuffer ans = new StringBuffer();

        int n = Math.max(a.length(), b.length()), carry = 0;
        for (int i = 0; i < n; ++i) 
            carry += i < a.length() ? (a.charAt(a.length() - 1 - i) - '0') : 0;
            carry += i < b.length() ? (b.charAt(b.length() - 1 - i) - '0') : 0;
            ans.append((char) (carry % 2 + '0'));
            carry /= 2;
        

        if (carry > 0) 
            ans.append('1');
        
        ans.reverse();

        return ans.toString();
    


二叉树的最小深度

给定一个二叉树,找出其最小深度。

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

说明:叶子节点是指没有子节点的节点。

这种类型的太多了,其实和前面的那个求深度的类似,只是这次要考虑到特殊情况。

class Solution 
    public int minDepth(TreeNode root) 
        if (root == null) 
            return 0;
        
        if(root.left == null && root.right == null)
            //是否为叶子节点是就直接返回1
            return 1;

        int left = this.minDepth(root.left);

        int right = this.minDepth(root.right);

        if(root.left==null || root.right==null)
            //这里主要是有特殊情况 就是 左边或者右边只有一边有节点的情况
            return left+right+1;
        

        return Math.min(left, right) + 1;
    

同构字符串

给定两个字符串 s 和 t,判断它们是否是同构的。

如果 s 中的字符可以按某种映射关系替换得到 t ,那么这两个字符串是同构的。

每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序。不同字符不能映射到同一个字符上,相同字符只能映射到同一个字符上,字符可以映射到自己本身。

示例 1:

输入:s = “egg”, t = “add”

输出:true

字符长度一样。
这个没什么好说的,和先前的模式串是一样的。

class Solution 
    public boolean isIsomorphic(String s, String t) 
        Map<Character, Character> Saskey = new HashMap<Character, Character>();
        Map<Character, Character> Taskey = new HashMap<Character, Character>();
        int len = s.length();
        for (int i = 0; i < len; ++i) 
            char x = s.charAt(i), y = t.charAt(i);
            if ((Saskey.containsKey(x) && Saskey.get(x) != y) || (Taskey.containsKey(y) && Taskey.get(y) != x)) 
                return false;
            
            Saskey.put(x, y);
            Taskey.put(y, x);
        
        return true;
    

day08(补)

反转链表


这里注意这里的链表是带头节点的单链表。

把后面的改成前面的不就好了。

class Solution 
    public ListNode reverseList(ListNode head) 
        ListNode prev = null;
        ListNode curr = head;
        while (curr != null) 
            ListNode next = curr.next;
            curr.next = prev;
            prev = curr;
            curr = next;
        
        return prev;
    


存在重复元素

给你一个整数数组 nums 。如果任一值在数组中出现 至少两次 ,返回 true ;如果数组中每个元素互不相同,返回 false 。

示例 1:

输入:nums = [1,2,3,1] 输出:true 示例 2:

输入:nums = [1,2,3,4] 输出:false

一看到这个,你肯定知道很多种解法,这里就提供最简便的解法。

直接使用集合,也就是hash。

class Solution 
    public boolean containsDuplicate(int[] nums) 
        Set<Integer> set = new HashSet<Integer>();
        for (int x : nums) 
            if (!set.add(x)) 
                return true;
            
        
        return false;
    


什么叫我手写一个hash函数,可以给钱我就写,给你好好分析分析set,hashmap源码,手把手教你修改java hash函数(好吧,这些都是基础)。

存在重复元素二

给你一个整数数组 nums 和一个整数 k ,判断数组中是否存在两个 不同的索引 i 和 j ,满足 nums[i] == nums[j]
且 abs(i - j) <= k 。如果存在,返回 true ;否则,返回 false 。

示例 1:

输入:nums = [1,2,3,1], k = 3 输出:true 示例 2:

输入:nums = [1,0,1,1], k = 1 输出:true 示例 3:

输入:nums = [1,2,3,1,2,3], k = 2 输出:false

这个的话一方面还是可以直接使用

class Solution 
    public boolean containsNearbyDuplicate(int[] nums, int k) 

        Map<Integer, Integer> map = new HashMap<>();
        for(int i=0;i<nums.length;i++)
            if(map.containsKey(nums[i]))
                if(Math.abs(i-map.get(nums[i]))<=k)
                    return true;
                
            
            map.put(nums[i],i);

        
        return false;
    

还有一个就是,这里的话指定了一个长度,所以我们这里可以考虑使用滑动窗口,这个只需要扫一次。当然map也是,因为查找的时间复杂度为O(1),按道理。

但是滑动的话是这样的,就相当于圈地嘛,在圈的地方里面有没有重复的,有就ok,没有就FALSE,直到滑动完了。

class Solution 
    public boolean containsNearbyDuplicate(int[] nums, int k) 
        Set<Integer> set = new HashSet<Integer>();
        int length = nums.length;
        for (int i = 0; i < length; i++) 
            if (i > k) 
                set.remove(nums[i - k - 1]);
            
            if (!set.add(nums[i])) 
                return true;
            
        
        return false;
    


用队列实现栈

请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。

实现 MyStack 类:

void push(int x) 将元素 x 压入栈顶。 int pop() 移除并返回栈顶元素。 int top() 返回栈顶元素。
boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。 注意:

你只能使用队列的基本操作 —— 也就是 push to back、peek/pop from front、size 和 is empty
这些操作。 你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 ,
只要是标准的队列操作即可。 示例:

输入:
[“MyStack”, “push”, “push”, “top”, “pop”, “empty”] [[], [1], [2],[], [], []]

输出: [null, null, null, 2, 2, false]

解释: MyStack myStack = new MyStack(); myStack.push(1); myStack.push(2);
myStack.top(); // 返回 2 myStack.pop(); // 返回 2 myStack.empty(); // 返回
False

这个没啥好说的,偷个懒(来个简单题水一水)
下面是python3.9的语法

class MyStack:

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.queue1 = collections.deque()
        self.queue2 = collections.deque()


    def push(self, x: int) -> None:
        """
        Push element x onto stack.
        """
        self.queue2.append(x)
        while self.queue1:
            self.queue2.append(self.queue1.popleft())
        self.queue1, self.queue2 = self.queue2, self.queue1


    def pop(self) -> int:
        """
        Removes the element on top of the stack and returns that element.
        """
        return self.queue1.popleft()


    def top(self) -> int:
        """
        Get the top element.
        """
        return self.queue1[0]


    def empty(self) -> bool:
        """
        Returns whether the stack is empty.
        """
        return not self.queue1

好吧还是给到java吧

class MyStack 
    Queue<Integer> queue1;
    Queue<Integer> queue2;

    /** Initialize your data structure here. */
    public MyStack() 
        queue1 = new LinkedList<Integer>();
        queue2 = new LinkedList<Integer>();
    
    
    /** Push element x onto stack. */
    public void push(int x) 
        queue2.offer(x);
        while (!queue1.isEmpty()) 
            queue2.offer(queue1.poll());
        
        Queue<Integer> temp = queue1;
        queue1 = queue2;
        queue2 = temp;
    
    
    /** Removes the element on top of the stack and returns that element. */
    public int pop() 
        return queue1.poll();
    
    
    /** Get the top element. */
    public int top() 
        return queue1.peek();
    
    
    /** Returns whether the stack is empty. */
    public boolean empty() 
        return queue1.isEmpty();
    


用栈实现队列

这个题目类似,就是反过来了(没错水上瘾了)

class MyQueue 
    Deque<Integer> inStack;
    Deque<Integer> outStack;

    public MyQueue() 
        inStack = new LinkedList<Integer>();
        outStack = new LinkedList<Integer>();
    
    
    public void push(int x) 
        inStack.push(x);
    
    
    public int pop() 
        if (outStack.isEmpty()) 
            in2out();
        
        return outStack.pop();
    
    
    public int peek() 
        if (outStack.isEmpty()) 
            in2out();
        
        return outStack.peek();
    
    
    public boolean empty() 
        return inStack.isEmpty() && outStack.isEmpty();
    

    private void in2out() 
        while (!inStack.isEmpty()) 
            outStack.push(inStack.pop());
        
    


你们可不能说我水就说这个简单呀(虽然这个确实是Letcode给初学者准备的(包括我))

day03(补)

这个day03其实就是我去送表姐的时候欠下的,但是我补了3题,所以这里补两题。(今天2022/1/19是我刷的第十天讲道理是50道Letcode或者蓝桥杯)

汇总区间

给定一个无重复元素的有序整数数组 nums 。
返回 恰好覆盖数组中所有数字 的 最小有序 区间范围列表。也就是说,nums 的每个元素都恰好被某个区间范围所覆盖,并且不存在属于某个范围但不属于 nums 的数字 x 。
列表中的每个区间范围 [a,b] 应该按如下格式输出:
“a->b” ,如果 a != b
“a” ,如果 a == b
示例 1:
输入:nums = [0,1,2,4,5,7]
输出:[“0->2”,“4->5”,“7”]
解释:区间范围是:
[0,2] --> “0->2”
[4,5] --> “4->5”
[7,7] --> “7”
示例 2:
输入:nums = [0,2,3,4,6,8,9]
输出:[“0”,“2->4”,“6”,“8->9”]
解释:区间范围是:
[0,0] --> “0”
[2,4] --> “2->4”
[6,6] --> “6”
[8,9] --> "8->9"

这个没啥好说的

class Solution39 
    public List<String> summaryRanges(int[] nums) 
        List<String> res = new ArrayList<String>();
        int i = 0;
        int n = nums.length;
        while (i < n) 
            int low = i;
            i++;
            while (i < n && nums[i] ==以上是关于每日一练(day09补08,03,04)的主要内容,如果未能解决你的问题,请参考以下文章

每日一练(day03--动态规划dp)

每日一练(day04)

每日一练(day11&look look Arrary.sort())

每日一练---- 3.02 3.03 3.04oj总结(类知识点)

每日一练---- 3.02 3.03 3.04oj总结(类知识点)

每日一练---- 3.02 3.03 3.04oj总结(类知识点)