前言:代码质量包括规范性(布局清晰,命名合理,手写能认出来),代码的完整性(功能测试,边界测试,负面测试)
文章目录
括号匹配
class Solution {
public boolean isValid(String s) {
if (s == null || s.length() == 0) {
return true;
}
Stack<Character> stack = new Stack<>();
for (char c: s.toCharArray()) {
if (c == '(' || c == '{' || c == '[') {
stack.push(c);
}
if (c == ')') {
if(stack.isEmpty() || stack.pop() != '(') {
return false;
}
}
if (c == '}') {
if (stack.isEmpty() || stack.pop() != '{') {
return false;
}
}
if (c == ']') {
if (stack.isEmpty() || stack.pop() != '[') {
return false;
}
}
}
//注意返回值,上述过程没返回false也不代表完全正确,因为可能左括号还没消除完,所以还得看它是否为空
return stack.isEmpty();
}
}
最小栈
思路
借助一个辅助栈来记录最小值!
为什么不使用一个整型记录最小值呢?
因为这样的话,如果那个值被弹出了,整型记录就失效了,更新会比较麻烦!
代码
class MinStack {
/** initialize your data structure here. */
Stack<Integer> stack;
Stack<Integer> minStack;
public MinStack() {
stack = new Stack<>();
minStack = new Stack<>();
}
public void push(int x) {
stack.push(x);
if (minStack.isEmpty() || x < minStack.peek()) {
minStack.push(x);
} else {
minStack.push(minStack.peek());
}
}
public void pop() {
minStack.pop();
stack.pop();
}
public int top() {
return stack.peek();
}
public int getMin() {
return minStack.peek();
}
}
用两个栈实现队列
直接上代码(结合注释看)
class MyQueue {
Stack<Integer> stack1;
Stack<Integer> stack2;
/** Initialize your data structure here. */
public MyQueue() {
stack1 = new Stack<Integer>();
stack2 = new Stack<Integer>();
}
public void push(int x) {
//装入只往第一个栈装
stack1.push(x);
}
//弹出时,如果第二个栈有值则直接冲第二个栈弹出,如果没有,那么就把第一个栈所有值都压入到第二个栈中
public int pop() {
if(empty()) {
return -1;
}
if (stack2.isEmpty()) {
while(!stack1.isEmpty()) {
stack2.push(stack1.pop());
}
}
return stack2.pop();
}
//查看和弹出同理
public int peek() {
if(empty()) {
return -1;
}
if (stack2.isEmpty()) {
while(!stack1.isEmpty()) {
stack2.push(stack1.pop());
}
}
return stack2.peek();
}
/** Returns whether the queue is empty. */
public boolean empty() {
return stack1.isEmpty() && stack2.isEmpty();
}
}
搜索旋转排序数组
代码
class Solution {
public int search(int[] num, int target) {
if (num == null || num.length == 0) {
return -1;
}
int start = 0;
int end = num.length - 1;
int mid;
while (start + 1 < end) {
mid = start + (end - start) / 2;
if (num[mid] == target) {
return mid;
}
//变化的就是这两个逻辑
if (num[mid] > num[start]) {
if (target <= num[mid] && num[start] <= target) {
end = mid;
} else {
start = mid;
}
} else {
if (target >= num[mid] && target <= num[end]) {
start = mid;
} else {
end = mid;
}
}
}
if (num[start] == target) {
return start;
}
if (num[end] == target) {
return end;
}
return -1;
}
}
寻找峰值(快手面试真题)
代码
class Solution {
public int findPeakElement(int[] nums) {
if (nums == null || nums.length == 0) {
return -1;
}
int start = 0;
int end = nums.length - 1;
int mid;
while(start + 1 < end) {
mid = start + (end - start) / 2;
if (nums[mid] < nums[mid - 1]) {
end = mid;
} else if (nums[mid] < nums[mid + 1]) {
start = mid;
} else {
return mid;
}
}
return nums[start] > nums[end] ? start : end;
}
}
两数之和 II - 输入有序数组
思路
直接双指针法,因为有序,如果当前双指针之和大于要求的数,那么就右指针向左走,如果和小于要求的数,那么左指针就向右走
代码
class Solution {
public int[] twoSum(int[] nums, int target) {
if (nums == null || nums.length == 0) {
return null;
}
int[] result = {-1, -1};
int start = 0;
int end = nums.length - 1;
while (start < end) {
if (nums[start] + nums[end] < target) {
start++;
} else if (nums[start] + nums[end] > target) {
end--;
} else {
result[0] = start + 1;
result[1] = end + 1;
break;
}
}
return result;
}
}
如果不止要求1对符合要求的数,那么找到一对后,就让左指针和右指针同时向中间走
有效三角形的个数
代码
class Solution {
public int triangleNumber(int[] nums) {
if (nums == null || nums.length < 3) {
return 0;
}
Arrays.sort(nums);
int total = 0;
//最大值从右到左
for (int k = nums.length - 1; k >= 2; k--) {
int start = 0;
int end = k - 1;
while (start < end) {
//如果大于,那么start到end的中间的所有值+end都满足
if (nums[start] + nums[end] > nums[k]) {
total += (end - start);
end --;
}
//如果小于,那么start就往右边走一个
else
{
start++;
}
}
}
return total;
}
}
1.数值的整次方
题目描述
实现函数double Power(double base, int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。
示例 1:
输入: 2.00000, 10
输出: 1024.00000
示例 2:
输入: 2.10000, 3
输出: 9.26100
示例 3:
输入: 2.00000, -2
输出: 0.25000
解释: 2-2 = 1/22 = 1/4 = 0.25
思路
注意指数为负数的情况,且注意0的0次方是没有意义的,返回1或0都是可以的
优化的公式
当n为偶数时,a的n次方=a的n/2次方a的n/2次方
当n为奇数时,a的n次方=a的(n-1)/2次方a的(n-1)/2次方*a
代码
class Solution {
public double myPow(double x, int n) {
//底数为0直接返回
if(x == 0) return 0;
long b = n;
double res = 1.0;
//指数小于0
if(b < 0) {
x = 1 / x;
b = -b;
}
while(b > 0) {
//&是与运算 2的2进制 10 1的2进制01 10&01结果为0 3的2进制 11 11&01结果为1
//b&1==1的话它就是奇数,b&1==0为偶数
//若b为偶数,这个只执行一次即b最后为1的时候,把x的值赋给res
if((b & 1) == 1) res *= x;
x *= x;
b >>= 1;
}
return res;
}
}
2.打印从1到最大的n位数
题目描述
输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999。
示例 1:
输入: n = 1
输出: [1,2,3,4,5,6,7,8,9]
说明:
用返回一个整数列表来代替打印
n 为正整数
待更
3.删除链表的节点
题目描述
给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。
返回删除后的链表的头节点。
注意:此题对比原题有改动
示例 1:
输入: head = [4,5,1,9], val = 5
输出: [4,1,9]
解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.
示例 2:
输入: head = [4,5,1,9], val = 1
输出: [4,5,9]
解释: 给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9.
代码
//注意 这个题目前提条件是肯定能找到该节点
class Solution {
public ListNode deleteNode(ListNode head, int val) {
//如果删除头结点是特殊情况,其它的删除中间节点和尾结点是一样的
//删除头结点直接返回头结点的后面那个指针,不管是空还是非空
if(head.val==val){
return head.next;
}
ListNode mySearch=head;
//记录mySearch前面的节点
ListNode preMySearch=null;
while(mySearch.val!=val){
preMySearch=mySearch;
mySearch=mySearch.next;
}
//删除节点
if(preMySearch!=null){
preMySearch.next=mySearch.next;
}
return head;
}
}
原题是在O(1)的时间内删除链表节点,已知头结点和要删除节点的指针。
思路
不要去遍历,而是选择把要删除节点的后面那个节点复制给删除节点,然后删除节点指向后面的节点的后面的节点,这样就是在O(1)时间内了。但是特殊情况删除尾部节点就还是需要遍历了
4.正则表达式匹配
题目描述
请实现一个函数用来匹配包含’. ‘和’‘的正则表达式。模式中的字符’.‘表示任意一个字符,而’'表示它前面的字符可以出现任意次(含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但与"aa.a"和"ab*a"均不匹配。
示例 1:
输入:
s = “aa”
p = “a”
输出: false
解释: “a” 无法匹配 “aa” 整个字符串。
示例 2:
输入:
s = “aa”
p = “a*”
输出: true
解释: 因为 ‘*’ 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 ‘a’。因此,字符串 “aa” 可被视为 ‘a’ 重复了一次。
示例 3:
输入:
s = “ab”
p = “."
输出: true
解释: ".” 表示可匹配零个或多个(’*’)任意字符(’.’)。
示例 4:
输入:
s = “aab”
p = “cab”
输出: true
解释: 因为 ‘*’ 表示零个或多个,这里 ‘c’ 为 0 个, ‘a’ 被重复一次。因此可以匹配字符串 “aab”。
示例 5:
输入:
s = “mississippi”
p = “misisp*.”
输出: false
s 可能为空,且只包含从 a-z 的小写字母。
p 可能为空,且只包含从 a-z 的小写字母以及字符 . 和 ,无连续的 '’。
思路
待更
5.表示数值的字符串
待更