题目一:

给你一个链表,每 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困难题(一)的更多相关文章

  1. leetcode刷题指南

    转载自:http://blog.csdn.net/lnho2015/article/details/50962989 以下是我个人做题过程中的一些体会: 1. LeetCode的题库越来越大,截止到目 ...

  2. 乘风破浪:LeetCode真题_025_Reverse Nodes in k-Group

    乘风破浪:LeetCode真题_025_Reverse Nodes in k-Group 一.前言 将一个链表按照一定的长度切成几部分,然后每部分进行翻转以后再拼接成一个链表是比较困难的,但是这也能锻 ...

  3. 乘风破浪:LeetCode真题_010_Regular Expression Matching

    乘风破浪:LeetCode真题_010_Regular Expression Matching 一.前言 关于正则表达式我们使用得非常多,但是如果让我们自己写一个,却是有非常大的困难的,我们可能想到状 ...

  4. 乘风破浪:LeetCode真题_006_ZigZag Conversion

    乘风破浪:LeetCode真题_006_ZigZag Conversion 一.前言 到这里我们对基本的问题有了一定的理解,其中字符串的操作一直是一个比较困难的问题,这一点我们需要认真对待,采用合理的 ...

  5. 乘风破浪:LeetCode真题_004_Median of Two Sorted Arrays

    乘风破浪:LeetCode真题_004_Median of Two Sorted Arrays 一.前言 说到算法,最难的就是一些需要通过分析得到一些递推公式或者有用的结论,进而用来解决问题的方法了. ...

  6. LeetCode刷题总结-数组篇(上)

    数组是算法中最常用的一种数据结构,也是面试中最常考的考点.在LeetCode题库中,标记为数组类型的习题到目前为止,已累计到了202题.然而,这202道习题并不是每道题只标记为数组一个考点,大部分习题 ...

  7. LeetCode刷题总结-数组篇(中)

    本文接着上一篇文章<LeetCode刷题总结-数组篇(上)>,继续讲第二个常考问题:矩阵问题. 矩阵也可以称为二维数组.在LeetCode相关习题中,作者总结发现主要考点有:矩阵元素的遍历 ...

  8. LeetCode刷题总结-数组篇(下)

    本期讲O(n)类型问题,共14题.3道简单题,9道中等题,2道困难题.数组篇共归纳总结了50题,本篇是数组篇的最后一篇.其他三个篇章可参考: LeetCode刷题总结-数组篇(上),子数组问题(共17 ...

  9. LeetCode刷题总结-双指针、位运算和分治法篇

    本文总结LeetCode上有关双指针.位运算和分治法的算法题,推荐刷题总数14道.具体考点分析如下图: 一.双指针 1.字符串和数组问题 题号:424. 替换后的最长重复字符,难度中等 题号:828. ...

随机推荐

  1. python函数编程闯关总结

    文件处理相关 1,编码问题 (1)请问python2与python3中的默认编码是什么? python .x默认的字符编码是ASCII,默认的文件编码也是ASCII python .x默认的字符编码是 ...

  2. .Net Core 2.0 App中读取appsettings.json

    引用: Microsoft.Extensions.ConfigurationMicrosoft.Extensions.Configuration.FileExtensionsMicrosoft.Ext ...

  3. C语言进行csv文件数据的读取

    C语言进行csv文件数据的读取: #include <stdio.h> #include <string.h> #include <malloc.h> #inclu ...

  4. 通过ping和tracert命令来判断网络经过多少个路由。trace和route合作

    摘抄自: https://blog.csdn.net/foreverhuylee/article/details/49853075 当我们访问某个网络时,通过tracert命令,就能知道本机与目标主机 ...

  5. 移动端rem屏幕设置

    //修改页面title var pageTitle=document.getElementsByTagName("title")[0].innerHTML; if(location ...

  6. 命令行选项解析函数getopt()

    1.定义: int getopt(int argc, char * const argv[], const char *optstring); 2.描述: getopt是用来解析命令行选项参数的,但是 ...

  7. Jenkins+Maven+Github+Springboot实现可持续自动部署(非常详细)

    目前公司开发的项目已经部署到服务器上,部署项目的测试环境和生产环境,加上每个项目n个服务,于是我就 , 骚就是骚,但是就是太累了,于是花点时间研究了一下Jenkins. Jenkins的作用和它的lo ...

  8. Spring Security教程(二):自定义数据库查询

    Spring Security教程(二):自定义数据库查询   Spring Security自带的默认数据库存储用户和权限的数据,但是Spring Security默认提供的表结构太过简单了,其实就 ...

  9. 复变函数知识总结(2)——Cauchy理论

    复变函数知识总结(2)——Cauchy理论 版本:2020-01-01 此版本不是最终版本,还有后续的补充和更新. 如有错误请指出,转载时请注明出处! page1 page2 page3 page4 ...

  10. Python:面向对象基础

    基本理论 什么是对象 万物皆对象 对象是具体的事物 拥有属性.行为 把许多零散的东西,封装成为一个整体 Python中一切东西都是对象,Python是一门特别彻底的面向对象编程语言(OOP) 其他编程 ...