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. ...
随机推荐
- 每天进步一点点------YUV格式详细解释
YUV格式详细解释 YUV开放分类: 网络.计算机.手机.色彩学.影像学 概述 YUV(亦称YCrCb)是被欧洲电视系统所采用的一种颜色编码方法(属于PAL),是PAL和SECAM模拟彩色电视制式 ...
- layuiAdmin pro v1.x 【单页版】开发者文档
layuiAdmin std v1.x [iframe版]开发者文档 题外 该文档适用于 layuiAdmin 专业版(单页面),阅读之前请务必确认是否与你使用的版本对应. 熟练掌握 layuiAdm ...
- sublime不支持ascill编码办法
1.按下组合键ctrl+shift+p,输入:install package,回车 2.在弹出的安装包框中搜索:ConvertToUTF8或者GBK Encoding Support,选择点击安装: ...
- 松软科技Web课堂:JavaScript HTML DOM 动画
基础页面 为了演示如何通过 JavaScript 来创建 HTML 动画,我们将使用一张简单的网页: 实例 <!DOCTYPE html> <html> <body> ...
- 12、API - 输入设备(API - Input Devices)
学习目录:树莓派学习之路-GPIO Zero 官网地址:https://gpiozero.readthedocs.io/en/stable/api_input.html 环境:UbuntuMeta-1 ...
- Python实现重命名一个文件夹下的图片
在网上查了一下python实现的图片重命名,工作中刚好用一下. # -*- coding:utf8 -*- import os path = '新建文件夹 (2)/' filelist = os.li ...
- Go语言基础之rand(随机数)包
在Golang中,有两个包提供了rand,分别为 "math/rand" 和 "crypto/rand", 对应两种应用场景. "math/rand ...
- MYSQL双查询错误2
一.关键点 MYSQL双查询错误之所以产生,有两个关键点: (1)SQL语句中使用GROUP BY语句时会生成临时表: (2)RAND()在查询和存储时生成的随机数有可能不同. 补充:======== ...
- mysql 远程连接不上,bind-address参数配置要求,以及怎么去使得mysql能够允许远程的客户端访问
刚安装了MySQL服务器,使用远程管理工具总是连接不上,因为知道mysql的默认端口是3306,于是使用telnet连接这个端口,(从这里可以学到telnet是可以这样用的) telnet 192.1 ...
- C语言:根据形参c中指定的英文字母,按顺序打印出若干后继相邻字母,-主函数中放入一个带头节点的链表结构中,h指向链表的头节点。fun函数找出学生的最高分-使用插入排序法对字符串中的字符进行升序排序。-从文件中找到指定学号的学生数据,读入次学生数据,
//根据形参c中指定的英文字母,按顺序打印出若干后继相邻字母,输出字母的大小与形参c一致,数量由形参d指定.例如:输入c为Y,d为4,则输出ZABC. #include <stdio.h> ...