代码随想录算法训练营day02 | leetcode 977/209/59
leetcode 977
分析1.0:
要求对平方后的int排序,而给定数组中元素可正可负,一开始有思维误区,觉得最小值一定在0左右徘徊,但数据可能并不包含0;遂继续思考,发现元素分布有三种情况,递增、递减以及类似二元凹函数,而题目要求O(n)的时间复杂度,不可能采用十大排序算法,于是接下来打算寻找最小值及其索引位置向两侧寻找次小值并存放进新数组,遍历元素时逐个使用Math.abs()函数确定大小,一开始采用指针移动的思想比较,index,index+1,index+2得到最小值及索引,但是在循环终止条件这里卡壳了,看到满屏幕的abs()下意识觉得不太对劲。换个思路,最终结果全是平方,是正数,那我一不做二不休,直接把元素变正或取平方,再遍历所有元素取最小值,思维上很清楚。在代码过程中遇到两个点,后文也会进行总结。1、int整数最大值Integer.MAX_VALUE,2、Math.pow(a,b)返回的是double类型元素,需转换,之后的思路就很清楚了,采用类似归并排序的算法解决问题。当然,一开始还是要考虑特殊情况。
代码如下
class Solution {
public int[] sortedSquares(int[] nums) {
int len = nums.length;
// 特殊考虑
if(len < 0){
return nums;
}
// 直接平方 注意int范围 pow方法返回double类型 可以直接两数相乘
for(int i = 0; i<len; i++){
nums[i] = (int)Math.pow(nums[i],2);
}
// 找最小值及下标 根据题目提示这里取10000000也可
int min = Integer.MAX_VALUE, minIndex = 0;
for(int i = 0; i<len; i++){
if(nums[i] < min){
min = nums[i];
minIndex = i;
}
}
// 从最小值处向两边比较选出次小值 直到一侧抵达数组边界
int[] ans = new int[len];
int index = 0;
ans[index++] = min;// 执行这条语句后index变为1
int left = minIndex-1, right = minIndex+1;
while(left >= 0 && right < len){
if(nums[left] <= nums[right]){
ans[index++] = nums[left--];
}else{
ans[index++] = nums[right++];
}
}
// 这里的index初值指向的位置一定是空的
while(left >= 0){
ans[index++] = nums[left--];
}
while(right < len){
ans[index++] = nums[right++];
}
return ans;
}
}
分析2.0:
我发现我的思路算得上是另一种形式的双指针,只不过是找到最小值后从中间往两边,而卡哥的思路是从两边往中间,interesting。这里就不po代码惹。
leetcode 209
分析1.0
第一印象就是for循环,从指向元素 i 开始,while循环累加i+1,i+2,i+3,复杂度最差是O(n2),很遗憾地超出了时间限制,只通过90%用例,要保证O(n)甚至O(logN)该咋办捏?
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int len = nums.length;
int ans = Integer.MAX_VALUE;
for(int i = 0; i<len; i++){
int sum = 0, j = i;
while(sum < target && j<len){
sum += nums[j++];
}
// 取最小值
if(j <= len && sum >= target){
ans = Math.min(ans,j - i);
// 日志
//System.out.println("i:"+i);
//System.out.println("j:"+j);
}
}
if(ans == Integer.MAX_VALUE){
return 0;
}
return ans;
}
}
ps. 上面的返回结果可以用三目运算符简化。
分析2.0
滑动窗口: 关键是窗口大小、左右边界如何移动。①窗口内元素和sum小于target ②右边界移动后sum超过target,记录长度,左边界右移,一直移动到右边界为止
犯错:左边界的移动触发只依赖于右边界移动时造成sum大于target,正解:左边界一旦移动就要在满足sum > target条件下一直移动到右边界为止
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int len = nums.length;
int ans = Integer.MAX_VALUE;
int sum = 0, start = 0;
// i为终止位置
for(int i=0; i<len; i++){
//System.out.println("for start:"+start+"------i:"+i);
sum += nums[i];
if(sum >= target){
while(start <= i && sum >= target){
//System.out.println("while start:"+start+"------i:"+i);
ans = Math.min(ans, i-start+1);
// 左边界右移 同时sum-左边界元素
sum -= nums[start++];
//System.out.println("start:"+start+"------i:"+i);
}
}
}
return ans == Integer.MAX_VALUE ? 0 : ans;
}
}
LeetCode 59
分析1.0
将整数1-n2螺旋填充进二维数组,在沿着上下左右某一方向填充时遇到边界或元素时进行转弯 右->下->左->上->右... i1 j1表示当前行当前列,第i1行 从j1列填充到第j2列,第j2列从 第i1行填充到第 i2 行,第 i2 行从第j2列填充到第填充到第j3列,第j3列从第i2行填充到第i3行 ...
注意点:
- 填充完一行或一列后要重新手动确定下一次填充起始位置
- 只有0处可以填充,所以不用担心子while循环什么时候退出
class Solution {
public int[][] generateMatrix(int n) {
int[][] nums = new int[n][n];
int i = 0, j = 0;
int element = 1;
while(element <= n*n){
// 右
while(j < n && nums[i][j] == 0){
nums[i][j++] = element++;
}
// 下
j--;i++;
while(i < n && nums[i][j] == 0){
nums[i++][j] = element++;
}
// 左
i--;j--;
while(j >= 0 && nums[i][j] == 0){
nums[i][j--] = element++;
}
j++;i--;
// 上
while(i >= 0 && nums[i][j] == 0){
nums[i--][j] = element++;
}
i++;j++;
}
return nums;
}
}
分析2.0
看了卡哥的思路,我还是更倾向于自己动手打出来的代码,关键在于模拟过程,出问题及时打日志。
总结:
- int整数最大值Integer.MAX_VALUE 2147483647 10位数
- Math.pow(a,b)返回的是double类型元素
- O(n)时间复杂度考虑、有序元素可考虑双指针、滑动窗口
- 看到问题写下自己的思路,逼着自己搞懂问题在问什么,把握住细枝末节的东西
代码随想录算法训练营day02 | leetcode 977/209/59的更多相关文章
- 【算法训练营day4】LeetCode24. 两两交换链表中的结点 LeetCode19. 删除链表的倒数第N个结点 LeetCode面试题 02.07. 链表相交 LeetCode142. 环形链表II
[算法训练营day4]LeetCode24. 两两交换链表中的结点 LeetCode19. 删除链表的倒数第N个结点 LeetCode面试题 02.07. 链表相交 LeetCode142. 环形链表 ...
- 【算法训练营day7】LeetCode454. 四数相加II LeetCode383. 赎金信 LeetCode15. 三数之和 LeetCode18. 四数之和
[算法训练营day7]LeetCode454. 四数相加II LeetCode383. 赎金信 LeetCode15. 三数之和 LeetCode18. 四数之和 LeetCode454. 四数相加I ...
- 【算法训练营day1】LeetCode704. 二分查找 LeetCode27. 移除元素
[算法训练营day1]LeetCode704. 二分查找 LeetCode27. 移除元素 LeetCode704. 二分查找 题目链接:704. 二分查找 初次尝试 看到题目标题是二分查找,所以尝试 ...
- 【算法训练营day8】LeetCode344. 反转字符串 LeetCode541. 反转字符串II 剑指Offer05. 替换空格 LeetCode151. 翻转字符串里的单词 剑指Offer58-II. 左旋转字符串
[算法训练营day8]LeetCode344. 反转字符串 LeetCode541. 反转字符串II 剑指Offer05. 替换空格 LeetCode151. 翻转字符串里的单词 剑指Offer58- ...
- 【算法题 14 LeetCode 147 链表的插入排序】
算法题 14 LeetCode 147 链表的插入排序: 解题代码: # Definition for singly-linked list. # class ListNode(object): # ...
- 代码随想录第十三天 | 150. 逆波兰表达式求值、239. 滑动窗口最大值、347.前 K 个高频元素
第一题150. 逆波兰表达式求值 根据 逆波兰表示法,求表达式的值. 有效的算符包括 +.-.*./ .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 注意 两个整数之间的除法只保留整数部分. ...
- 代码随想录第八天 |344.反转字符串 、541. 反转字符串II、剑指Offer 05.替换空格 、151.翻转字符串里的单词 、剑指Offer58-II.左旋转字符串
第一题344.反转字符串 编写一个函数,其作用是将输入的字符串反转过来.输入字符串以字符数组 s 的形式给出. 不要给另外的数组分配额外的空间,你必须原地修改输入数组.使用 O(1) 的额外空间解决这 ...
- 代码随想录第二天| 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II
2022/09/22 第二天 第一题 这题我就直接平方后排序了,很无脑但很快乐啊(官方题解是双指针 第二题 滑动窗口的问题,本来我也是直接暴力求解发现在leetCode上超时,看了官方题解,也是第一次 ...
- Manacher算法学习笔记 | LeetCode#5
Manacher算法学习笔记 DECLARATION 引用来源:https://www.cnblogs.com/grandyang/p/4475985.html CONTENT 用途:寻找一个字符串的 ...
- 程序员进阶之算法练习:LeetCode专场
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由落影发表 前言 LeetCode上的题目是大公司面试常见的算法题,今天的目标是拿下5道算法题: 题目1是基于链表的大数加法,既考察基本 ...
随机推荐
- 【Java SE进阶】Day07 等待与唤醒案例、线程池、Lamdba表达式
一.等待唤醒机制 1.线程间通信 多个线程处理同一个资源,就存在线程通信问题(线程间存在竞争与协作机制) 为什么处理:为了 保证多个线程有规律地完成同一任务 如何处理:避免对共享变量争夺,需要等待唤醒 ...
- elasticsearch倒排索引(全面了解)
SimpleAI推荐语: 前年转过这篇文章,最近在看检索相关论文,发现又有点忘记倒排索引(inverted index)的具体内容,遂翻出来再看看,不得不说,这个漫画画的太好了,娓娓道来,一看就懂,再 ...
- f-strings: Python字符串处理的瑞士军刀
从 3.6 开始,Python 新增了一个格式化字符串的方法,称之为 f-string. 其用法就是在python原始字符串的基础上增加 f/F 前缀,以大括号 {} 标明被替换的字段. f-stri ...
- Jmeter 函数助手之__time
接口中需要传入time时,可使用Jmeter 函数助手中的__time函数传入当前时间 格式和参数名称两个字段非必填,当都不填时直接点击生成按钮,得到13位时间戳:按图填写后,得到10位时间戳,获取当 ...
- des_招标
网站 aHR0cHM6Ly9jdGJwc3AuY29tLyMv 翻到第二页,加载了一个2,并且返回的都是加密的数据 点到initiator,可以看到发送的Axios请求,尝试全局搜索intercep ...
- 痞子衡嵌入式:对比恩智浦全系列MCU(包含Kinetis/LPC/i.MXRT/MCX)的GPIO电平中断设计差异
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦全系列MCU(包含Kinetis, LPC, i.MXRT, MCX)的GPIO电平中断设计差异. 在痞子衡旧文 <以i.M ...
- Ubuntu:Docker 容器操作
创建容器 1.docker run [option] 镜像名 [向启动容器中传入的命令] 常用可选说明 -i 表示以"交互模式"运行容器 -t 表示容器启动后会进入其命令行.加入这 ...
- 【基础篇】一文带你掌握 Redis
一.摘要 谈起 Redis,相信大家都不会陌生,做过云平台开发的程序员多多少少会接触到它,Redis 英文全称:Remote Dictionary Server,也被称之为远程字典服务. 从官方的定义 ...
- Request.Form&Request.QueryString实现伪ajax的效果
1.问题描述 最近一直在搞公司老系统的需求开发,前端是asp,后端的vb.碰到了一个需求,是做一个"日志查询"功能,查询条件为:时间&操作人. 原本我的设计思路是异步查询, ...
- day14-功能实现13
家居网购项目实现013 以下皆为部分代码,详见 https://github.com/liyuelian/furniture_mall.git 32.功能30-会员不能登录后台管理 32.1需求分析/ ...