LeetCode题目练习记录 _数组和链表02 _20211008

11. 盛最多水的容器

难度中等2834

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

说明:你不能倾斜容器。

示例 1:

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

示例 2:

输入:height = [1,1]
输出:1

示例 3:

输入:height = [4,3,2,1,4]
输出:16

示例 4:

输入:height = [1,2,1]
输出:2

提示:

  • n == height.length
  • 2 <= n <= 105
  • 0 <= height[i] <= 104

方法一:双指针 左右指针,短板弃之

// java
class Solution {
public int maxArea(int[] height) {
int left = 0;
int right = height.length -1;
int ans = 0;
while(left < right) {
int area = Math.min(height[left],height[right]) * (right-left);
ans = Math.max(ans,area);
if (height[left] <= height[right]){
++left;
}else{
--right;
}
}
return ans;
}
}
// go
func maxArea(height []int) int {
i,j :=0,len(height)-1
m:=0
for i<j{
cur:=(j-i)*min(height[i],height[j])
if cur>m{
m=cur
}
if (height[i]<height[j]) {
i++
}else {
j--
}
}
return m
} func min(x,y int) int {
if x>y {
return y
}
return x
}
// go
func maxArea(height []int) int {
lenA := len(height)
i,j :=0,lenA-1
maxAreaC := 0
// 更直接的运算方式 会带来更快的 运行速度
for{
if i == j {
break
} write := false
minH := height[i]
if height[j]<minH{
minH = height[j]
write = true
}
curArea := (j-i)*minH if write{
j --
}else{
i++
} if curArea > maxAreaC{
maxAreaC = curArea
}
}
return maxAreaC
}

方法二:暴力 ——会超时!

// java
class Solution {
public int maxArea(int[] height) { int maxarea = 0;
for (int i = 0; i < height.length; i++)
for (int j = i + 1; j < height.length; j++)
maxarea = Math.max(maxarea, Math.min(height[i], height[j]) * (j - i));
return maxarea;
}
}

283. 移动零

难度简单1259

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

示例:

输入: [0,1,0,3,12]
输出: [1,3,12,0,0]

说明:

  1. 必须在原数组上操作,不能拷贝额外的数组。
  2. 尽量减少操作次数。

方法一:双指针 —— 快慢指针法

// go
// 双指针 —— 快慢指针法
func moveZeroes(nums []int) {
left, right, n := 0, 0, len(nums)
for right < n {
if nums[right] != 0 {
nums[left], nums[right] = nums[right], nums[left]
left ++
}
right ++
}
}
// 右指针走在前,左指针走在后,如果右指针指向 0 不要动它,右指针继续超前遍历,遇到非0就和左指针交换,交换之后左指针 向前一步 右指针也要向前,这样就能保证 把所有非0元素移动到前面来

方法二:双指针 —— 补0覆盖

// go
func moveZeroes(nums []int) {
nowIdx := 0
for _,x := range nums {
if x != 0 {
nums[nowIdx] = x
nowIdx++
}
}
for i := nowIdx; i < len(nums); i++ {
nums[i] = 0
}
}

70. 爬楼梯

难度简单1924

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

注意:给定 n 是一个正整数。

示例 1:

输入: 2
输出: 2
解释: 有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶

示例 2:

输入: 3
输出: 3
解释: 有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶

这本质就是一个数学题,需要一定的线代知识,太多思路就不展开了,官方题解都有

方法一:动态规划

// go
func climbStairs(n int) int {
p, q, r := 0, 0, 1
// 一步没走,现在只有一个办法,去走上第一级台阶
for i := 1; i <= n; i++ { // 走起来了
p = q // 走上上一个台阶需要的步数
q = r // 走上一个台阶需要的步数
r = p + q // 走当前台阶需要的步数
// 不断迭代,小步慢走
}
return r
}

方法二:矩阵快速幂

// go
type matrix [2][2] int func climbStairs(n int) int {
res := pow(matrix{{1,1},{1,0}},n)
return res[0][0]
} func pow(a matrix,n int) matrix {
res := matrix{{1,0},{0,1}}
for ; n > 0; n >>= 1 {
if n&1 == 1 {
res = mul(res, a)
}
a = mul(a,a)
}
return res
} func mul(a, b matrix) (c matrix) {
for i :=0; i < 2; i++ {
for j := 0; j < 2; j++ {
c[i][j] = a[i][0] * b[0][j] + a[i][1] * b[1][j]
}
}
return c
}

方法三:通项公式

// go
func climbStairs(n int) int {
sqrt5 := math.Sqrt(5)
pow1 := math.Pow((1+sqrt5)/2,float64(n + 1))
pow2 := math.Pow((1-sqrt5)/2,float64(n + 1))
return int(math.Round((pow1-pow2)/sqrt5))
}

15. 三数之和

难度中等3846

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

示例 1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]

示例 2:

输入:nums = []
输出:[]

示例 3:

输入:nums = [0]
输出:[]

提示:

  • 0 <= nums.length <= 3000
  • -105 <= nums[i] <= 105
// java
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
if(nums == null || nums.length <= 2){
return Collections.emptyList();
}
Set<List<Integer>> result = new LinkedHashSet<>();
Arrays.sort(nums);
for(int i=0;i<nums.length-2;i++){
int head = i+1;
int tail = nums.length -1;
while(head<tail){
int sum = - (nums[head]+nums[tail]);
if(sum == nums[i]){
List<Integer> value = Arrays.asList(nums[i],nums[head],nums[tail]);
result.add(value);
}
if(sum <= nums[i]){
tail--;
}else{
head++;
}
}
}
return new ArrayList<>(result);
}
}
// go
func threeSum(nums []int) [][]int {
n := len(nums)
sort.Ints(nums)
ans := make([][]int, 0)
for first := 0;first < n; first ++ {
if first > 0 && nums[first] == nums[first - 1] {
continue
}
third := n-1
target := -1 * nums[first]
for second := first + 1 ;second < n ; second++ {
if second > first + 1 && nums[second] == nums[second - 1] {
continue
}
for second < third && nums[second] + nums[third] > target {
third--
}
if second == third {
break
}
if nums[second] + nums[third] == target { // if a + b = -c 将 abc加入结果集
ans = append(ans,[]int{nums[first],nums[second],nums[third]})
}
}
}
return ans
}
// js
var threeSum = function(nums){
let arr = [];
nums.sort((a,b) => {
return a - b;
})
for(let i = 0;i < nums.length;i++){
if(i > 0 && nums[i] === nums[i - 1]) continue;
let left = i + 1,right = nums.length - 1;
let a = nums[i];
while(left < right){
let b = nums[left];
let c = nums[right];
if(a + b + c === 0){
arr.push([a,b,c]);
//神来之笔,诸位道友有想过for循环这么用吗
for(left++;left < right && nums[left] === nums[left - 1];left++);
}else if(a + b + c < 0){
left++;
}else{
right--;
}
}
}
return arr;
}

LeetCode题目练习记录 _数组和链表02 _20211008的更多相关文章

  1. Leetcode题目34.在排序数组中查找元素的第一个和最后一个位置(中等)

    题目描述: 给定一个按照升序排列的整数数组 nums,和一个目标值 target.找出给定目标值在数组中的开始位置和结束位置. 你的算法时间复杂度必须是 O(log n) 级别. 如果数组中不存在目标 ...

  2. Leetcode题目21.合并两个有序链表(简单)

    题目描述: 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1->2->4, 1->3->4输出:1->1-& ...

  3. leetcode题库练习_数组中重复的数字

    题目:数组中重复的数字 找出数组中重复的数字. 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次 ...

  4. Net基础篇_学习笔记_第九天_数组_冒泡排序(面试常见题目)

    冒泡排序: 将一个数组中的元素按照从大到小或从小到大的顺序进行排列. for循环的嵌套---专项课题 int[] nums={9,8,7,6,5,4,3,2,1,0}; 0 1 2 3 4 5 6 7 ...

  5. leetcode题目234.回文链表(快慢指针+辅助空间-简单)

    题目描述: 请判断一个链表是否为回文链表. 示例 1: 输入: 1->2 输出: false 示例 2: 输入: 1->2->2->1 输出: true 进阶: 你能否用 O( ...

  6. Leetcode题目206.反转链表(简单)

    题目描述: 反转一个单链表. 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL 进阶: ...

  7. LeetCode题目解答

    LeetCode题目解答——Easy部分 Posted on 2014 年 11 月 3 日 by 四火 [Updated on 9/22/2017] 如今回头看来,里面很多做法都不是最佳的,有的从复 ...

  8. LeetCode题目答案及理解汇总(持续更新)

    面试算法题 dfs相关 全排列 #include<bits/stdc++.h> using namespace std; const int N = 10; //用一个path数组来存储每 ...

  9. 数组和链表--Java学习笔记(一)

    版权声明: 本文由Faye_Zuo发布于http://www.cnblogs.com/zuofeiyi/, 本文可以被全部的转载或者部分使用,但请注明出处. 我是一个全职妈妈,两年前在上海一家人力资源 ...

  10. LeetCode 题目总结/分类

    LeetCode 题目总结/分类 利用堆栈: http://oj.leetcode.com/problems/evaluate-reverse-polish-notation/ http://oj.l ...

随机推荐

  1. 微服务全链路跟踪:jaeger增加tag参数

    微服务全链路跟踪:grpc集成zipkin 微服务全链路跟踪:grpc集成jaeger 微服务全链路跟踪:springcloud集成jaeger 微服务全链路跟踪:jaeger集成istio,并兼容u ...

  2. 如何诱导AI犯罪-提示词注入

    我们用到的大模型基本把政治类信息.犯罪相关信息都已屏蔽.但是,黑客依旧可以使用提示词诱导和提示词注入的方式对大模型进行攻击. 1.提示词诱导 如果直接让AI提供犯罪过程,AI会直接拒绝.虽然AI对于大 ...

  3. JavaScript设计模式样例十四 —— 观察者模式

    观察者模式(Observer Pattern) 定义:当一个对象被修改时,则会自动通知它的依赖对象.目的:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被 ...

  4. React挂载dom无效的问题

    话不多说,先上代码. 根据我的猜测,ReactDOM.render()这个函数,也就是挂载的意思是将内容进行替换,所以我的vdom1在调试的时候没有展示出来. 然后我创建了两个div块,分别挂载vdo ...

  5. 使用go+gin编写日志中间,实现自动化收集http访问信息,错误信息等,自动化生成日志文件

    1.首先在logger包下 点击查看代码 package logger import ( "fmt" "io" "net/http" &qu ...

  6. 注册中心Nacos集群搭建

    一提到注册中心,大家往往想到Zookeeper.或者Eureka.今天我们看看阿里的一款配置中心+注册中心的中间件--Nacos.有了它以后,我们的项目中的配置就可以统一从Nacos中获取了,而且Sp ...

  7. kubernetes重新初始化“[ERROR DirAvailable--var-lib-etcd]”

    [root@master01 ~]# kubeadm init --config /root/kubeadm-config.yaml --upload-certs [init] Using Kuber ...

  8. Vue.js 异步组件传参

    本文主要展示一下如何给异步组件进行参数传递: 通过 h 函数就可以啦 versions: vue@3.2.13 子组件 Async.vue <template> <div> & ...

  9. APP专项测试之兼容性测试

    1.APP 兼容性测试认识 随着 APP 应用范围越来越广,用户群体越来越大,终端设备的型号也越来越多,移动终端碎片化加剧,使得 APP 兼容性测试成为测试质量保障必须要考虑的环节. APP 兼容性测 ...

  10. SpringMVC —— 入门案例执行流程

    启动服务器初始化过程 1.服务器启动,执行ServletContainersInitConfig类,初始化web容器    2.执行createServletApplicationContext方法, ...