每日一练(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)的主要内容,如果未能解决你的问题,请参考以下文章
每日一练(day11&look look Arrary.sort())
每日一练---- 3.02 3.03 3.04oj总结(类知识点)