个人主页:天海奈奈的博客
刷题专栏: 题库 - 力扣 (LeetCode) 全球极客挚爱的技术成长平台面试top
刷题网站: 力扣 让我们一起加油~
目录
20. 有效的括号
21. 合并两个有序链表
26. 删除有序数组中的重复项
2. 两数相加
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。
示例 1:
输入:s = "()"
输出:true
示例 2:
输入:s = "()[]{}"
输出:true
示例 3:
输入:s = "(]"
输出:false
这个题我们需要判断所给的字符串中的前后括号是否能成对存在,也就是一一对应的关系。
既然括号是成对存在并且我们只需要判断对错,根据括号一一对应的性质我们考虑红使用栈的方法来解决,遍历的时候出现左括号我们就将对应的右括号入栈,利用栈的同进同出的性质,当遍历到右括号时如果右括号存在且在栈顶,我们就出栈如果没有或不是同一种类我们就出栈
代码实现
class Solution {
public boolean isValid(String s) {
Stack stack = new Stack<>();
char[] chars = s.toCharArray();
//遍历所有的元素
for (char c : chars) {
//如果是左括号,就把他们对应的右括号压栈
if (c == '(') {
stack.push(')');
} else if (c == '{') {
stack.push('}');
} else if (c == '[') {
stack.push(']');
} else if (stack.isEmpty() || stack.pop() != c) {
//否则就只能是右括号。
//1,如果栈为空,说明括号无法匹配。
//2,如果栈不为空,栈顶元素就要出栈,和这个右括号比较。
//如果栈顶元素不等于这个右括号,说明无法匹配,
//直接返回false。
return false;
}
}
//最后如果栈为空,说明完全匹配,是有效的括号。
//否则不完全匹配,就不是有效的括号
return stack.isEmpty();
}
}
这个题我们要合并两个有序链表,我们新建一个链表,只要有一个链表没完我们就不停,比对两个链表当前节点的大小,将小的接入新建链表,一个链表空了就直接接入未空链表。
代码实现
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
ListNode dummyHead = new ListNode(0);
ListNode cur = dummyHead;
while (list1 != null && list2 != null) {
if (list1.val < list2.val) {
cur.next = list1;
cur = cur.next;
list1 = list1.next;
} else {
cur.next = list2;
cur = cur.next;
list2 = list2.next;
}
}
// 任一为空,直接连接另一条链表
if (list1 == null) {
cur.next = list2;
} else {
cur.next = list1;
}
return dummyHead.next;
}
}
给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。
由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有 k 个元素,那么 nums 的前 k 个元素应该保存最终结果。
将最终结果插入 nums 的前 k 个位置后返回 k 。
不要使用额外的空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
判题标准:
系统会用下面的代码来测试你的题解:
int[] nums = [...]; // 输入数组
int[] expectedNums = [...]; // 长度正确的期望答案
int k = removeDuplicates(nums); // 调用
assert k == expectedNums.length;
for (int i = 0; i < k; i++) {
assert nums[i] == expectedNums[i];
}
如果所有断言都通过,那么您的题解将被 通过。
示例 1:
输入:nums = [1,1,2]
输出:2, nums = [1,2,_]
解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。
示例 2:
输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5, nums = [0,1,2,3,4]
解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。
使用双指针,这题第一遍做过了,i来存数字,j来遍历数组,j != i, i++ 并将j对应的值赋给 i。遍历完成后j会遍历到数组尾部,有几个不同的数字i的下标就是i-1。
代码实现
class Solution {
public int removeDuplicates(int[] nums) {
int i = 0;
for(int j = 1;j < nums.length; j++){
if(nums[i] != nums[j]){
i++;
nums[i] = nums[j];
}
}
return i+1;
}
}
看他那提示就能看出来其实就是写反过来的两个数相加,只不过我们输出的时候相加的结果也是反过来的 既然要反过来我们就直接反着做,返回值类型是链表也不用考虑位数,那我们直接把链表当前节点进行相加,对10取余的到个位,把这个数加进新链表,十位如果有进位就再当前节点和的基础上加入进位。这个题的关键就是要考虑到进位的问题
代码实现
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
//新链表,头结点
ListNode blindNode = new ListNode(0);
//pre为当前节点的前一个节点
ListNode preNode = blindNode;
int curry = 0;//curry来放进位的数
while(l1 != null || l2 != null || curry != 0){
int sum = curry;//
if(l1 != null){//第一个链表
sum = sum + l1.val;
l1 = l1.next;
}
if(l2 != null){//第二个
sum = sum + l2.val;
l2 = l2.next;
}
preNode.next = new ListNode(sum % 10);//个位
curry = sum /10;//十位
preNode = preNode.next;
}
return blindNode.next;
}
}