LeetCode困难题(一)
题目一:
给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。
k 是一个正整数,它的值小于或等于链表的长度。
如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。
示例 :
给定这个链表:1->2->3->4->5
当 k = 2 时,应当返回: 2->1->4->3->5
当 k = 3 时,应当返回: 3->2->1->4->5
方法一:
1、这是一个给定一个反转数链表反转,先实现整个链表反转;
2、设置pre=null,curr=head, while(curr!=null) 定义一个新的节点保证当前节点的下一个节点 ListNode temp=curr.next;
3、curr.next=pre将当前节点指针往前指,然后将当前节点赋值给pre,curr=temp,最后返回pre,就是反转后的链表;
4、下面实现多个链表的反转,先设置一个哑结点,ListNode dummy=new ListNode(0);
5、ListNode dummy.next=head,ListNode pre=dummy,end=dummy;
6、开始通过判断end进行循环,while(end!=null) for(int i=0;i<k&&end!=null) end=end.next;
7、如果end==null表示剩下的节点小于阈值k,直接跳出循环break;
8、定义一个next节点存放end的最后指向的位置 ListNode=end.next,在定义一个开始节点ListNode start=pre.next;
9、end.next断开链表,end.next=null;
10、pre.next=reverse(start)实现链表的反转,将start放置到最后;
11、将start指向之前end存放的节点,start.next=next;
12、pre节点和end节点都赋值给start;
13、返回哑结点dummy.next;
具体代码:
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
ListNode dummy=new ListNode(0);
dummy.next=head;
ListNode pre=dummy;
ListNode end=dummy;
while(end!=null)
{
for(int i=0;i<k&&end!=null;i++) end=end.next;
if(end==null) break;
ListNode next=end.next;
ListNode start=pre.next;
end.next=null;
pre.next=reverse(start);
start.next=next;
pre=start;
end=start;
}
return dummy.next;
}
public ListNode reverse(ListNode head)
{
ListNode pre=null;
ListNode curr=head;
while(curr!=null)
{
ListNode temp=curr.next;
curr.next=pre;
pre=curr;
curr=temp;
}
return pre;
}
}
题目二:
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
示例:
输入: [0,1,0,2,1,0,1,3,2,1,2,1]
输出: 6
方法一:
1、对每一列进行遍历,求出每一列的接水量;
2、整体的思路是,对于每一列求出其左边最大值和右边最大值,再求其最小值,将这个最小值和这个列进行比较;
3、如果最小值>列长度,则min-nums[i],否则接水量为0;
具体代码:
class Solution {
public int trap(int[] height) {
int sum=;
for(int i=;i<height.length-;i++)
{
int left_max=;
for(int j=i-;j>=;j--)
{
if(height[j]>left_max)
left_max=height[j];
}
int right_max=;
for(int j=i+;j<height.length-;j++)
{
if(height[j]>right_max)
right_max=height[j];
}
int min=Math.min(left_max, right_max);
if(height[i]<min)
sum=sum+(min-height[i]);
}
return sum;
}
}
方法二:
1、对于上述的方法使用了二重循环时间复杂度较高,每次都需要确定某一值的左边最大值和右边最大值;
2、我们想要减少上面的重复计算,用动态规划将数值进行存储;
3、动态方程:max_left[i]=Math.max(max_left[i-1],height[i-1]);
4、对于右采用同样的方式,需要求其最小值,直接进行调用,int min=Math.min(max_left[i],max_right[i]);
5、思路和方法一基本相同,只是用空间换取时间;
具体代码:
class Solution {
public int trap(int[] height) {
int sum=0;
int max_left[]=new int[height.length];
int max_right[]=new int[height.length];
for(int i=1;i<height.length-1;i++)
max_left[i]=Math.max(max_left[i-1], height[i-1]);
for(int i=height.length-2;i>=0;i--)
max_right[i]=Math.max(max_right[i+1], height[i+1]);
for(int i=1;i<height.length-1;i++)
{
int min=Math.min(max_left[i], max_right[i]);
if(height[i]<min)
sum=sum+(min-height[i]);
}
return sum;
}
}
方法三:
1、双指针
具体代码:
public int trap(int[] height) {
int sum = 0;
int max_left = 0;
int max_right = 0;
int left = 1;
int right = height.length - 2; // 加右指针进去
for (int i = 1; i < height.length - 1; i++) {
//从左到右更
if (height[left - 1] < height[right + 1]) {
max_left = Math.max(max_left, height[left - 1]);
int min = max_left;
if (min > height[left]) {
sum = sum + (min - height[left]);
}
left++;
//从右到左更
} else {
max_right = Math.max(max_right, height[right + 1]);
int min = max_right;
if (min > height[right]) {
sum = sum + (min - height[right]);
}
right--;
}
}
return sum;
}
题目三:
给定一个未排序的整数数组,找出其中没有出现的最小的正整数。
示例 1:
输入: [1,2,0]
输出: 3
示例 2:
输入: [3,4,-1,1]
输出: 2
方法:
1、这道题的思路不是很容易能够想到,首先将数组中所有的小于等于0和大于n的数赋值为1;
2、然后将其进行转换变为负数,这个算法最精彩的部分是将转换后的数组的元素作为另一个元素的下标,并且将其赋值为绝对值的负值;
3、这样实现了数组中每一个前n个元素,出现过就将其设定为负值;
4、最后遍历循环,直到出现大于0的数就是我们要求的值,将其下标返回;
5、当然如果开始数组没有1,那么返回1为结果;
具体代码:
class Solution {
public int firstMissingPositive(int[] nums) {
int n=nums.length;
int contain=0;
for(int i=0;i<nums.length;i++)
{
if(nums[i]==1)
{
contain++;
break;
}
}
if(contain==0)
return 1;
if(n==1)
return 2;
for(int i=0;i<n;i++)
{
if(nums[i]<=0||nums[i]>n)
{
nums[i]=1;
}
}
for(int i=0;i<n;i++)
{
int a=Math.abs(nums[i]);
if(a==n)
nums[0]=-Math.abs(nums[0]);
else
{
nums[a]=-Math.abs(nums[a]);
}
}
for(int i=1;i<n;i++)
{
if(nums[i]>0)
return i;
}
if(nums[0]>0)
return n;
return n+1;
}
}
题目四:
给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配。
'.' 匹配任意单个字符
'*' 匹配零个或多个前面的那一个元素
所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。
方法一:
1、使用递归,可能不是很容易想到,模式字符串中有' .'和‘ *’,不知道应该如何下手;
2、其实着手点就在于*号,*号出现位置至少应该在第二位,就需要先判断第一个字符是否相同;
3、boolean first_match=s.charAt(0)==p.charAt(0)||p.charAt(0)==' .';
4、如果模式串的长度大于2并且第二位是*,就可以进行递归实现,return isMatch(s,p.substring(2))||first_match&&isMacth(s.substring(1),p);
5、否则,都向后移动一位;
具体代码:
class Solution {
public boolean isMatch(String s, String p) {
if(p.isEmpty()) return s.isEmpty();
boolean first_match=(!s.isEmpty())&&(s.charAt(0)==p.charAt(0)||p.charAt(0)=='.');
if(p.length()>=2&&p.charAt(1)=='*')
{
return (isMatch(s, p.substring(2)))||(first_match&&isMatch(s.substring(1), p));
}
else
{
return first_match&&isMatch(s.substring(1), p.substring(1));
}
}
}
LeetCode困难题(一)的更多相关文章
- leetcode刷题指南
转载自:http://blog.csdn.net/lnho2015/article/details/50962989 以下是我个人做题过程中的一些体会: 1. LeetCode的题库越来越大,截止到目 ...
- 乘风破浪:LeetCode真题_025_Reverse Nodes in k-Group
乘风破浪:LeetCode真题_025_Reverse Nodes in k-Group 一.前言 将一个链表按照一定的长度切成几部分,然后每部分进行翻转以后再拼接成一个链表是比较困难的,但是这也能锻 ...
- 乘风破浪:LeetCode真题_010_Regular Expression Matching
乘风破浪:LeetCode真题_010_Regular Expression Matching 一.前言 关于正则表达式我们使用得非常多,但是如果让我们自己写一个,却是有非常大的困难的,我们可能想到状 ...
- 乘风破浪:LeetCode真题_006_ZigZag Conversion
乘风破浪:LeetCode真题_006_ZigZag Conversion 一.前言 到这里我们对基本的问题有了一定的理解,其中字符串的操作一直是一个比较困难的问题,这一点我们需要认真对待,采用合理的 ...
- 乘风破浪:LeetCode真题_004_Median of Two Sorted Arrays
乘风破浪:LeetCode真题_004_Median of Two Sorted Arrays 一.前言 说到算法,最难的就是一些需要通过分析得到一些递推公式或者有用的结论,进而用来解决问题的方法了. ...
- LeetCode刷题总结-数组篇(上)
数组是算法中最常用的一种数据结构,也是面试中最常考的考点.在LeetCode题库中,标记为数组类型的习题到目前为止,已累计到了202题.然而,这202道习题并不是每道题只标记为数组一个考点,大部分习题 ...
- LeetCode刷题总结-数组篇(中)
本文接着上一篇文章<LeetCode刷题总结-数组篇(上)>,继续讲第二个常考问题:矩阵问题. 矩阵也可以称为二维数组.在LeetCode相关习题中,作者总结发现主要考点有:矩阵元素的遍历 ...
- LeetCode刷题总结-数组篇(下)
本期讲O(n)类型问题,共14题.3道简单题,9道中等题,2道困难题.数组篇共归纳总结了50题,本篇是数组篇的最后一篇.其他三个篇章可参考: LeetCode刷题总结-数组篇(上),子数组问题(共17 ...
- LeetCode刷题总结-双指针、位运算和分治法篇
本文总结LeetCode上有关双指针.位运算和分治法的算法题,推荐刷题总数14道.具体考点分析如下图: 一.双指针 1.字符串和数组问题 题号:424. 替换后的最长重复字符,难度中等 题号:828. ...
随机推荐
- 任意模数 n 次剩余
\(n\) 次剩余 你需要解方程 \(x^n\equiv k\pmod m\),其中 \(x\in [0,m-1]\). 保证解数不超过 \(C=10^6\) \(1\le n,m,k\le 10^9 ...
- web前端技能考核(阿里巴巴)
- openresty-component
1.Array Var Nginx Module ArrayVarNginxModulelocation /foo { array_split ',' $arg_files to=$array; # ...
- 【C语言】编写程序,输出以下图形
编写程序输出以下图形: * ** *** **** ***** 代码: #include <stdio.h> int main() { int i, j; ; i <= ; i++) ...
- 使用MQTT.fx客户端接入阿里云
一.前期准备. 1.关于MQTT连接的属性:https://www.cnblogs.com/mhtc/p/11112153.html 2.关于阿里云配置工具的使用:https://www.cnblog ...
- mvn 搭建临时仓库批量下载依赖jar包
1.新建文件夹temp,在temp下新建setup.bat ,pom.xml 2.编辑setup.bat 和pom.xml bsetup.bat call mvn -f pom.xml depende ...
- 关于umask的计算方式(简单任性)
1.对于文件夹[d]来说 用755-umask 3.对与文件[f]来说,在2的基础上减掉x属性就完事儿(有x的,减掉1,没有的,就什么也不管) 再来个手绘版本的举例
- php之新的开始---php的相关及其环境搭建
写在前面:首先,感谢“奇矩”给的这次机会,不论结果如何,我都会尽我最大的努力! 在今晚之前,如果说,我与php的接触是停留在知道的阶段,那今晚过后,我想我算是认识了php.php作为一门编程语言,已经 ...
- 《Web安全攻防 渗透测试实战指南 》 学习笔记 (三)
Web安全攻防 渗透测试实战指南 学习笔记 (三) burp suite详解 是一款集成化渗透测试工 ...
- Cat4500升级注意事项
第一部分:升级ROMMON 可以通过release note去查看什么Supervisor建议什么样的版本.例如:ROMMON Release Notes for the WS-X45-SUP7-E, ...