标签归档:LeetCode

LeetCode-118-119-121-141-155

118 Pascal’s Triangle119 Pascal’s Triangle II121 Best Time to Buy and Sell Stock141 Linked List Cycle155 Min Stack 均较为简单,合并完成解题报告。

118 Pascal’s Triangle

概述

帕斯卡三角绘制。

分析

所谓帕斯卡三角,也叫做杨辉三角(也是贾宪三角……),解释可以在维基百科上得知。

那么只需按照定义,逐层生成即可。

解法

119 Pascal’s Triangle II

概述

只绘制杨辉三角的某行。

分析

属于118 Pascal’s Triangle的扩展题目,可以考虑直接复用118的代码,生成后返回。

问题在于时间复杂度过高。后续可以优化。

解法

121 Best Time to Buy and Sell Stock

概述

给出股价列表,找出最大的获利。

分析

可以想到,获利最大,即买入价最低,卖出价最高。

每个时间段都会有最高的卖出价,在数组中,一个区间的最大值是一定的。从后向前遍历,如果当前值不大于当前位置之后的最大值,那么当前值开始的最大值,仍然是当前值之后的最大值。反之则是当前值。

只需要针对价格,再次遍历数组,获得每个位置的数字的差值,即可知道在哪一位置时获利最大,即差值最大。

解法

141 Linked List Cycle

概述

判断单向链表中是否存在环。

分析

简单的做法,用hash存储当前的节点指针值,如果再次遇到这一指针,说明有环。

但是目前还没有做出不需要额外空间的做法。

解法

155 Min Stack

概述

用单向链表实现一个可以直接获得最小值的栈。

分析

栈的特点是先进后出。

push 操作,可以看做是更换首节点的操作。同时,由于要直接获得最小值,可以入栈时判断是否比当前的最小值更小,由此可以完成更新操作。

pop 操作,可以看做是删除首节点的操作。同样的,如果pop的数值比小于等于最小值,需要遍历链表找到最小值。

如是,随时获得栈最小值的时间复杂度是O(1)

解法

leetcode-66-67-83-217

标题中提到的4道题目都较为简单,合并到一起写解题记录。

66 Plus One

概述

Plus One 即给定以数组形式表示各位的数字,将这一数字加1的结果输出为数组即可。

分析

这一题主要处理的是常规的运算的进位问题,同时,由于数组并没有确定数字为int,那么位数不定,需要按照正常的竖式运算的步骤进行。

当计算发现最高位需要进位时,申请更大的空间,返回结果。

解法

67 Add Binary

概述

Add Binary66 Plus One 很相似,只不过由十进制数变为了二进制数的加法。

输入是字符串,输出也是字符串。

分析

二进制加法,仍然按照竖式计算的方式进行即可。无需多说。

解法

83 Remove Duplicates from Sorted List

概述

Remove Duplicates from Sorted List 即在已排序的单向链表中完成去重。

分析

链表已排序,去重工作变得相当容易,只需要判断当前节点的值是否等于上一节点的值,如果等于则将链表当前的下一指针指向下下一个节点,周而复始。

解法

217 Contains Duplicate

概述

Contains Duplicate 判断数组中是否有重复的值。

分析

使用Hash完成这一判断最为容易,判断一个值是否在 HashMap 中存在即可。

解法

LeetCode-24-26-27

24 Swap Nodes in Pairs

概述

Swap Nodes in Pairs 即是将相邻的两个节点交换形成新的链表,要求在于不能修改值,只能做链表节点操作。

对于空间复杂度上也要要求,只能在 O(1) 这个复杂度上完成。

分析

对于链表操作,无需多说,这里需要注意的地方在于:

  • 第一组元素(前2个)的第二个节点需要变成新链表的首节点
  • 在循环中,前一组的第一个节点要连接的是下一组的第二个节点

明确上述两个关键步骤之后,需要做的就是申请变量暂存目前处理节点的位置以及记录上一组节点的第一个节点。

解法

 

26 Remove Duplicates from Sorted Array

概述

Remove Duplicates from Sorted Array 即通过数组元素移动操作,去除数组中重复的数字,并且返回不重复数字的个数。

分析

本题的需要注意,单纯返回非重复数字的长度是不够的,由于空间复杂度也有要求,需要在原数组中通过移位等操作将重复元素删除。

在是已经排序了的数组的情况下,相同数字必然是连续的,只需要遍历一遍数字,遇到相同的数字,将下一数字之后的数组元素前移即可。

下一次循环开始的

解法


 

27 Remove Element

概述

Remove Element 同样是remove,和26的区别是给定的数字进行去除。

分析

Remove Duplicates from Sorted Array 的解法类似,不同的是考虑终止条件的时候需要注意删除了元素之后相当于产生了一个数组,长度是发生了变化,循环时需要考虑这一因素。

解法

 

其他

26 与 27 逐个搬迁并不是最佳解法,还有优化的空间。

LeetCode-19-20-21

19 Remove Nth Node From End of List

概述

Remove Nth Node From End of List 即删除单向链表中从链表尾部开始的第N个节点。

分析

单向链表只能通过逐步前进才能到达指定节点,是无法在 O(1) 的时间复杂度下拿到链表的长度的,可以考虑通过一次遍历将链表明确节点节点位置与值的对应关系,之后通过链表的节点操作完成删除节点的效果。

节点位置与值的关系可以通过Hash进行存储,由于链表长度不定,预先留出数组空间的方式个人认为并不是好的选择。

解法


 

20 Valid Parentheses

概述

Valid Parentheses 即判断括号是否匹配。

分析

括号需要一一对应,即一个左括号,需要对应一个右括号,简单来说,在字符串遍历过程中,右括号出现之后,需要判断上一个括号是不是一个左括号,如果是一个左括号,那么说明这个括号完成了匹配。否则,说明没有完成匹配。

从数据结构上来说,是一个非常适合的数据结构,左括号直接入栈,出现右括号则比较栈顶元素,如果相同,则出栈,继续比较,否则则说明不匹配。完成比较之后,如果栈已空,则说明括号完成了完全的匹配。

但是,使用字符串操作其实也能做到这一效果,完全不需要使用 Java 内置的栈。即栈顶元素可以看成是字符串的最后一个元素,出栈则是删除最后一个字符串。

解法

 

21 Merge Two Sorted Lists

概述

Merge Two Sorted Lists 即单向链表归并。

分析

归并已排序链表,首先需要判断两个链表是否已经到达链表终点,达到链表终点之后只需要处理另一个没有到达终点的链表。

在两个链表没有到达终点时,比较二者的首节点的值,在升序的情况下,较小的值添加到结果链表中,较小值所在的链表向前前进一个节点,之后周而复始的比较。

解法

 

LeetCode-9

概述

Palindrome Number 判断文字是否是回文,输出布尔值。

分析

作为一道 Easy 的题目,看起来并不是特别麻烦,不过这题要求无需增加附加的空间复杂度。

题目要求判断是否为回文数,那么负数肯定不是回文数,因为负数带有符号位。

从字符串的角度来看,回文只需判断反转之后是否相同即可,那么针对数字亦可以使用这一方法。

考虑到数字反转之后会出现溢出的情况,而正数溢出之后在 Java 中的处理方式则是变为一个负数(参见 SO 上的问题 How does Java handle integer underflows and overflows and how would you check for it?),那么反转后变为负数的数字自然不是一个回文数了,因为反转之后在非负整数的范围内显然这个数字不存在。

不新增变量的情况下,只能通过递归来解决问题了。

解法