博主个人博客网站:文客
这个系列主要记录在力扣刷题的总结和问题
如果你想每天和我一起刷题,可以关注一下我的个人博客网站:文客,我会每天在这里更新技术文章和面试题,也会及时收到大家的评论与留言,欢迎各位大佬来交流!
设计一个支持 push
,pop
,top
*** 作,并能在常数时间内检索到最小元素的栈。
实现 MinStack
类:
MinStack()
初始化堆栈对象。void push(int val)
将元素val推入堆栈。void pop()
删除堆栈顶部的元素。int top()
获取堆栈顶部的元素。int getMin()
获取堆栈中的最小元素。
示例 1:
输入:
["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]
输出:
[null,null,null,null,-3,null,0,-2]
解释:
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); --> 返回 -3.
minStack.pop();
minStack.top(); --> 返回 0.
minStack.getMin(); --> 返回 -2.
思路:
看题解有用链表来实现的,用链表也是一个很好的思路,但是均摊下来,复杂度并不低。我是直接使用Stack,然后维护一个最小值,每次插入元素时,都与最小值比较,如果有更小的元素插入进来,就更新最小值。当出栈的元素为最小值时,遍历栈,更新最小值,这里是O(n)的复杂度,但是从概率学的角度来想,又不是每次都会d出最小的元素,所以我想也是可以接受的。
题解:class MinStack {
Stack<Integer> stack;
Integer minVal;
public MinStack() {
stack = new Stack<>();
minVal = Integer.MAX_VALUE;
}
public void push(int val) {
stack.push(val);
if(val < minVal){
minVal = val;
}
}
public void pop() {
int popVal = stack.pop();
if(popVal == minVal){
minVal = Integer.MAX_VALUE;
for(int num : stack){
minVal = Math.min(minVal,num);
}
}
}
public int top() {
return stack.peek();
}
public int getMin() {
return minVal;
}
}
/**
* Your MinStack object will be instantiated and called as such:
* MinStack obj = new MinStack();
* obj.push(val);
* obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.getMin();
*/
160. 相交链表
给你两个单链表的头节点 headA
和 headB
,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null
。
图示两个链表在节点 c1
开始相交**:**
题目数据 保证 整个链式结构中不存在环。
注意,函数返回结果后,链表必须 保持其原始结构 。
自定义评测:
评测系统 的输入如下(你设计的程序 不适用 此输入):
intersectVal
- 相交的起始节点的值。如果不存在相交节点,这一值为0
listA
- 第一个链表listB
- 第二个链表skipA
- 在listA
中(从头节点开始)跳到交叉节点的节点数skipB
- 在listB
中(从头节点开始)跳到交叉节点的节点数
评测系统将根据这些输入创建链式数据结构,并将两个头节点 headA
和 headB
传递给你的程序。如果程序能够正确返回相交节点,那么你的解决方案将被 视作正确答案 。
示例 1:
输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,6,1,8,4,5], skipA = 2, skipB = 3
输出:Intersected at '8'
解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,6,1,8,4,5]。
在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。
示例 2:
输入:intersectVal = 2, listA = [1,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
输出:Intersected at '2'
解释:相交节点的值为 2 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [1,9,1,2,4],链表 B 为 [3,2,4]。
在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。
示例 3:
输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
输出:null
解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。
由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。
这两个链表不相交,因此返回 null 。
思路:
先计算两个链表的长度,然后把他们的起点对其,依次遍历,如果有相同节点,证明相交,直接返回相交节点,如果没有找到则返回null
题解:/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
int len1 = 0;
int len2 = 0;
ListNode p1 = headA;
ListNode p2 = headB;
while(p1 != null){
len1++;
p1 = p1.next;
}
while(p2 != null){
len2++;
p2 = p2.next;
}
p1 = (len1 > len2) ? headA : headB;
p2 = (p1 == headA) ? headB : headA;
for(int i = 0; i < Math.abs(len1 - len2); i++){
p1 = p1.next;
}
while(p1 != null && p2 != null){
if(p1 == p2){
return p1;
}
p1 = p1.next;
p2 = p2.next;
}
return null;
}
}
169. 多数元素
给定一个大小为 n
的数组 nums
,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋
的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入:nums = [3,2,3]
输出:3
示例 2:
输入:nums = [2,2,1,1,1,2,2]
输出:2
思路:
多数元素,即是众数。最简单暴力的方式就是先排序,然后返回下标为nums.length / 2的数据。
效率最高的方式是摩尔计数法。维护一个计数器,当计数器为0时,将当前值赋予res,遇到相同元素计数器加一,遇到不同元素计数器减一。最后返回res,一定是出现次数最多的。
题解:class Solution {
public int majorityElement(int[] nums) {
int res = 0;
int count = 0;
for(int i = 0; i < nums.length; i++){
if(count == 0){
res = nums[i];
count++;
} else if(res != nums[i]){
count--;
} else if(res == nums[i]){
count++;
}
}
return res;
}
}
215. 数组中的第K个最大元素
给定整数数组 nums
和整数 k
,请返回数组中第 **k**
个最大的元素。
请注意,你需要找的是数组排序后的第 k
个最大的元素,而不是第 k
个不同的元素。
示例 1:
输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
示例 2:
输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4
思路:
使用优先级队列,队列的大小为k,堆顶就是第k大的元素。
题解:class Solution {
PriorityQueue<Integer> queue;
public int findKthLargest(int[] nums, int k) {
queue = new PriorityQueue<>(k);
for(int num : nums){
if(queue.size() < k){
queue.offer(num);
} else if(queue.peek() < num){
queue.poll();
queue.offer(num);
}
}
return queue.peek();
}
}
221. 最大正方形
在一个由 '0'
和 '1'
组成的二维矩阵内,找到只包含 '1'
的最大正方形,并返回其面积。
示例 1:
输入:matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]
输出:4
示例 2:
输入:matrix = [["0","1"],["1","0"]]
输出:1
示例 3:
输入:matrix = [["0"]]
输出:0
思路:
使用dp,dp数组代表i,j位置内,最大正方形的边长
题解:class Solution {
public int maximalSquare(char[][] matrix) {
int[][] dp = new int[matrix.length + 1][matrix[0].length + 1];
int len = 0;
for(int i = 1; i <= matrix.length; i++){
for(int j = 1; j <= matrix[0].length; j++){
if(matrix[i - 1][j - 1] == '1'){
dp[i][j] = 1 + Math.min(dp[i - 1][j - 1], Math.min(dp[i - 1][j],dp[i][j - 1]));
len = Math.max(len,dp[i][j]);
}
}
}
return len * len;
}
}
博客原文地址
力扣刷题小记7
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)