def __init__(self):
self.Que_1 = []
self.Que_2 = []
def push(self, x: int) -> None:
# Push element x onto stack.
self.Que_1.append(x)
def pop(self) -> int:
# Removes the element on top of the stack and returns that element.
while len(self.Que_1)>1:
self.Que_2.append(self.Que_1.pop(0))
res = self.Que_1.pop(0)
self.Que_1, self.Que_2 = self.Que_2, self.Que_1
self.Que_2.clear()
return res
def top(self) -> int:
# Get the top element.
while len(self.Que_1)>1:
self.Que_2.append(self.Que_1.pop(0))
res = self.Que_1[0]
self.Que_2.append(self.Que_1.pop(0))
self.Que_1, self.Que_2 = self.Que_2, self.Que_1
self.Que_2.clear()
return res
def empty(self) -> bool:
return not self.Que_1
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def splitListToParts(self, head: Optional[ListNode], k: int) -> List[Optional[ListNode]]:
if not head:
return [None for _ in range(k)]
length = 0
node = head
while node:
length += 1
node = node.next
# 计算每段的长度以及多出的部分
avg_len, extra_len = length//k, length%k
# 再次遍历链表,根据 avg_len 和 extra_len 将链表分割成 k 个部分
# 并将每个部分的尾节点的 next 指针置为空。
res = []
cur = head
pre = None
for _ in range(k):
res.append(cur)
for _ in range(avg_len+(1 if extra_len > 0 else 0)):
pre = cur
cur = cur.next
if pre:
pre.next = None
extra_len -= 1
return res
class MinStack {
Deque<Integer> stack;
Deque<Integer> minStack;
/** initialize your data structure here. */
public MinStack() {
stack = new LinkedList<>();
minStack = new LinkedList<>();
}
public void push(int x) {
stack.offerLast(x);
if(minStack.isEmpty() || x <= minStack.peekLast()) {
minStack.offerLast(x);
}
}
public void pop() {
int i = stack.pollLast();
if(i == minStack.peekLast()) {
minStack.pollLast();
}
}
public int top() {
return stack.peekLast();
}
public int getMin() {
return minStack.peekLast();
}
}
/**
* Your MinStack object will be instantiated and called as such:
* MinStack obj = new MinStack();
* obj.push(x);
* obj.pop();
* int param_3 = obj.top();
* int param_4 = obj.getMin();
*/
class Solution {
public int[] spiralArray(int[][] array) {
if(array==null||array.length==0){
return new int[0];
}
int m = array.length;
int n = array[0].length;
int[] res = new int[m*n];
int up = 0;//上边界
int down = m-1;//下边界
int left = 0;//左边界
int right = n-1;//右边界
int index = 0;
while(up<=down||left<=right){
//往右走
for(int i=left;i<=right;i++){
res[index++] = array[up][i];
}
up++;
if(up>down){
break;
}
//往下走
for(int i=up;i<=down;i++){
res[index++] = array[i][right];
}
right--;
if(right<left){
break;
}
//往左走
for(int i = right;i>=left;i--){
res[index++] = array[down][i];
}
down--;
if(down<up){
break;
}
//往上走
for(int i = down;i>=up;i--){
res[index++] = array[i][left];
}
left++;
if(left>right){
break;
}
}
return res;
}
}
思路:定义左边界、有边界、上边界和下边界,然后可以向右走、向下走、
向左走和向上走,同时创建一个res数组用来保存访问到的数组元素
时间复杂度:O(mn)
空间复杂度:O(1)
数学+迭代法:
class Solution {
public int iceBreakingGame(int num, int target) {
int x = 0;
for (int i = 2; i <= num; i++) {
x = (x + target) % i;
}
return x;
}
}
链表法,模拟删除,但是后面会超时:
class Solution {
public int iceBreakingGame(int num, int target) {
Node pre = new Node();
Node cur = pre;
//构造环形数组
for(int i=0;i<num;i++){
cur.next = new Node(i,null);
cur = cur.next;
}
cur.next = pre.next;//现在cur指向的是最后一个元素
cur = cur.next;//此时cur指向第一个元素
while(cur.next!=cur){
int count = 1;
while(count<target){
cur = cur.next;//往后走一步
count++;
}
//把cur所指向的节点删除
cur.val = cur.next.val;
cur.next = cur.next.next;
}
return cur.val;
}
}
class Node{
int val;
Node next;
public Node(){
}
public Node(int val,Node next){
this.val = val;
this.next = next;
}
}
class Solution {
public int trainWays(int num) {
final int MOD = 1000000007;
if(num==0){
return 1;
}
if(num<=2){
return num;
}
int first = 1;
int second = 2;
for(int i=3;i<=num;i++){
int temp = first+second;
first = second;
second = temp%MOD;
}
return second;
}
}
思路:小青蛙一次可以跳一阶,也可以跳两阶,所以如果要知道跳num阶有多少中情况,只需要之后num-1或者num-2有多少阶就好了。
时间复杂度:O(n)
空间复杂度:O(1)
class Solution {
public int fib(int n) {
final int MOD = 1000000007;
if(n<=1){
return n;
}
int first = 0;
int second = 1;
for(int i=2;i<=n;i++){
int temp = first+second;
first = second;
second = temp%MOD;
}
return second;
}
}
时间复杂度:O(n)
空间复杂度:O(1)
需要注意题意里的取模部分,给我恶心坏了
“`c++
class Solution {
public:
vector spiralArray(vector>& array) {
if (array.empty()) return {};
int m = array.size(), n = array[0].size();
vector ans(m*n, 0);
int idx = 0;
int l = 0, r = n-1, t = 0, b = m-1;
while (true) {
// top row: t, j = [l -> r]
for (int j=l; j<=r; j++) {
ans[idx++] = array[t][j];
}
// top row is over.
if (++t > b) break;
// right col: i = [t -> b], r
for (int i=t; i<=b; i++) {
ans[idx++] = array[i][r];
}
// right col is over.
if (--r < l) break;
// bottom row: b, j = [r -> l]
for (int j=r; j>=l; j–) {
ans[idx++] = array[b][j];
}
// bottom row is over.
if (–b < t) break;
// left col: i = [b -> l], l
for (int i=b; i>=t; i–) {
ans[idx++] = array[i][l];
}
// left col is over.
if (++l > r) break;
}
return ans;
}
};
“`
class Solution {
public int iceBreakingGame(int num, int target) {
List list = new ArrayList<>();
for(int i = 0; i < num; i++)
list.add(i);
int current = 0;
for(int i = 0; i < num – 1; i++){
current = (current + target -1) % list.size();
list.remove(current);
}
return list.get(0);
}
}//空间On2
//时间On
//链表解法
class Solution {
public int iceBreakingGame(int num, int target) {
int ans = 0;
for(int i = 2; i <= num; i++){
ans = (ans + target) % i;
}
return ans;
}
}//数学解法
class Solution {
public int trainWays(int num) {
if(num<=1) return 1;
if(num==2) return 2;
int a=1;
int b=2;
int c=0;
for(int i=3;i<=num;i++){
c=(a+b)%1000000007;
a=b;
b=c;
}
return c;
}
}
class Solution {
public int[] spiralArray(int[][] array) {
if(array.length 0)
return new int[0];
int[] ans = new int[array.length * array[0].length];
ans[0] = array[0][0];
int count = 1;
int left = 0;
int right = array[0].length – 1;
int top = 0;
int bottom = array.length – 1;
int direction = 0;//右 下 左 上
int i = 0, j = 0;
while(left <= right && top <= bottom ){
class Solution {
public int iceBreakingGame(int num, int target) {
return f(num,target);
}
// 返回值为最后留下的元素的号码
public int f(int num,int target){
// 退出递归的条件
if(num==1) return 0;
// 关系:长度为num的序列删除了一个后成为长度为 num -1的序列
int x = f(num-1,target);
return (target + x) % num;
}
}
class CQueue:
时间复杂度: O(1),push 为 O(1),pop 为均摊 O(1)。对于每个元素,至多入栈和出栈各两次(Stack_In和Stack_Out至多各进出栈一次),故均摊复杂度为 O(1)。
空间复杂度:O(n)。其中 n 是操作总数。对于有 n 次 push 操作的情况,队列中会有 n 个元素,故空间复杂度为 O(n)。
class MyStack:
入栈操作(push):O(1)
出栈操作(pop):平均情况下接近O(1),最坏情况下O(n)
获取栈顶元素(top):平均情况下接近O(1),最坏情况下O(n)
判空操作(empty):O(1)
class CQueue:
时间复杂度: O(1),push 为 O(1),pop 为均摊 O(1)。对于每个元素,至多入栈和出栈各两次(Stack_In和Stack_Out至多各进出栈一次),故均摊复杂度为 O(1)。
空间复杂度:O(n)。其中 n 是操作总数。对于有 n 次 push 操作的情况,队列中会有 n 个元素,故空间复杂度为 O(n)。
思路分析
复杂度分析
参考力扣725.分隔链表,k恒定为3即可。
阅读打卡
利用差值存入栈中可以保证O(1)的空间复杂度
时间复杂度O(n),空间复杂度O(n)
时间复杂度O(1),空间复杂度O(n)
class Solution {
public int nthUglyNumber(int n) {
int a = 1, b = 1, c = 1;
int[] dp = new int[n+1];
dp[1] = 1;
for(int i=2; i<=n; i++){
dp[i] = Math.min(dp[a]2, Math.min(dp[b]3, dp[c]5));
if(dp[i] dp[a]2) a++;
if(dp[i] dp[b]3) b++;
if(dp[i] dp[c]5) c++;
}
}
时间:O(n);
空间:O(n)
class Solution {
public int dismantlingAction(String arr) {
int n = arr.length();
int ans = 0;
}
时间:O(n)
空间:O(n)
class Solution {
public int jewelleryValue(int[][] frame) {
int m = frame.length;
int n = frame[0].length;
}
时间:O(mn)
空间:O(mn)
class Solution {
public int bestTiming(int[] prices) {
int n = prices.length;
if(n <= 1) return 0;
}
时间:O(n)
空间:O(1)
子问题: dp[i] = max(dp[i-1],dp[i-2]+nums[i-1]);
打卡
“`
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
if(list1 == null){
return list2;
}else if(list2 == null){
return list1;
}
if(list1.val <= list2.val){ list1.next = mergeTwoLists(list1.next, list2); return list1; }else{ list2.next = mergeTwoLists(list1, list2.next); return list2; }
class Solution {
public int minPathSum(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
}
时间:O(mn)
空间:O(mn)
class Solution {
public int maxSales(int[] sales) {
int n = sales.length;
}
时间:O(n)
空间:O(n)
“`
//首先逆序然后使用链表反转
public ListNode reverseKGroup(ListNode head, int k) {
思路:模拟顺时针打印矩阵,需要注意边界情况
“`c++ spiralArray(vector>& array) { ans(m*n, 0);
class Solution {
public:
vector
if (array.empty()) return {};
int m = array.size(), n = array[0].size();
vector
int idx = 0;
int l = 0, r = n-1, t = 0, b = m-1;
while (true) {
// top row: t, j = [l -> r]
for (int j=l; j<=r; j++) { ans[idx++] = array[t][j]; } // top row is over. if (++t > b) break;
// right col: i = [t -> b], r
for (int i=t; i<=b; i++) { ans[idx++] = array[i][r]; } // right col is over. if (--r < l) break; // bottom row: b, j = [r -> l]
for (int j=r; j>=l; j–) {
ans[idx++] = array[b][j];
}
// bottom row is over.
if (–b < t) break; // left col: i = [b -> l], l
for (int i=b; i>=t; i–) {
ans[idx++] = array[i][l];
}
// left col is over.
if (++l > r) break;
}
return ans;
}
};
“`
思路:约瑟夫环
class Solution {
public int calculateMinimumHP(int[][] dungeon) {
int[][] dp = new int[dungeon.length][dungeon[0].length];
dp[dungeon.length-1][dungeon[0].length-1] = 1 + Math.max(0, – dungeon[dungeon.length-1][dungeon[0].length-1]);
for(int i = dungeon.length – 2; i >= 0; i–){
dp[i][dungeon[0].length – 1] = Math.max(1,dp[i + 1][dungeon[0].length – 1] – dungeon[i][dungeon[0].length – 1]);
}
for(int j = dungeon[0].length – 2; j >= 0; j–){
dp[dungeon.length – 1][j] = Math.max(1, dp[dungeon.length – 1][j + 1] – dungeon[dungeon.length – 1][j]);
}
}
//dp
//空间复杂度On2
//时间复杂度On2
class Solution { list = new ArrayList<>();
public int iceBreakingGame(int num, int target) {
List
for(int i = 0; i < num; i++)
list.add(i);
int current = 0;
for(int i = 0; i < num – 1; i++){
current = (current + target -1) % list.size();
list.remove(current);
}
return list.get(0);
}
}//空间On2
//时间On
//链表解法
class Solution {
public int iceBreakingGame(int num, int target) {
int ans = 0;
for(int i = 2; i <= num; i++){
ans = (ans + target) % i;
}
return ans;
}
}//数学解法
class Solution {
public int nthUglyNumber(int n) {
int[] dp = new int[n];
int i = 0, j = 0, k = 0;
dp[0] = 1;
int current = 1;
while(current < n){
int min = Math.min(dp[i] * 2,Math.min(dp[j] * 3,dp[k] * 5));
dp[current++] = min;
if(min dp[i] * 2) i++;
if(min dp[j] * 3) j++;
if(min dp[k] * 5) k++;
}
return dp[n-1];
}
//时间复杂度On 空间复杂度On
class Solution {
public int trap(int[] height) {
int[] water = new int[height.length];
int i = 0;
int ans = 0;
while(i < height.length){
int curentHeight = height[i];
int j = i + 1;
while(j < height.length){
if(height[j] < height[i])
j++;
else
break;
}
if(j < height.length){
for(int k = i + 1; k < j; k++ )
water[k] = height[i];
}
i = j ;
}
i = height.length – 1;
while(i >= 0){
int j = i – 1;
while(j >= 0){
if(height[j] < height[i])
j–;
else
break;
}
if(j >= 0 ){
for(int k = i – 1; k > j; k– )
water[k] = height[i];
}
i = j ;
}
for(int h = 0; h < height.length; h++)
ans += Math.max(water[h] – height[h],0);
return ans;
}
}
//来回两次遍历 时间复杂度On 空间复杂度On
class Solution {
public int trap(int[] height) {
int ans = 0;
int i = 0;
int leftMax = height[i];
int j = height.length – 1;
int rightMax = height[j];
while(i < j){
if(height[i] < height[j]){
ans += leftMax – height[i];
i++;
leftMax = Math.max(leftMax,height[i]);
}
else{
ans += rightMax – height[j];
j–;
rightMax = Math.max(rightMax,height[j]);
}
}
return ans;
}
}//优化法 空间复杂度降到O1
时间复杂度:O(nm)
额外空间复杂度:O(nm)
//时间复杂度On
//空间复杂度O1
时间复杂度:O(n+m)
额外空间复杂度:O(1)
时间复杂度o(n),空间复杂度o(n)
时间复杂度:O(n)
额外空间复杂度:O(1)
打卡
“`java queue = new LinkedList<>();
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
Queue
List
> res = new ArrayList<>();> decorateRecord(TreeNode root) {>(); t = new ArrayList<>();
public List
if(root == null) return new ArrayList
queue.add(root);
int count =0;
while(!queue.isEmpty() && root != null){
count++;
List
int size = queue.size();
for(int i = 0; i< size; i++){ TreeNode temp = queue.poll(); if(count%2==1){ t.add(temp.val); } if(count%2==0){ t.add(0,temp.val); }
}
死循环中按照右下左上的顺序依次提取元素,每次提取一个元素之后都要判断还能否继续遍历
class Solution {
public int findRepeatDocument(int[] documents) {
int cur = 0;
while(cur < documents.length){
if(documents[cur] cur){
cur++;
continue;
}
if(documents[documents[cur]] documents[cur])
return documents[cur];
int temp = documents[documents[cur]];
documents[documents[cur]] = documents[cur];
documents[cur] = temp;
}
return -1;
}
}
//时间复杂度On
//空间复杂度O1
class Solution {
public int[] spiralArray(int[][] array) {
if(array.length 0)
return new int[0];
int[] ans = new int[array.length * array[0].length];
ans[0] = array[0][0];
int count = 1;
int left = 0;
int right = array[0].length – 1;
int top = 0;
int bottom = array.length – 1;
int direction = 0;//右 下 左 上
int i = 0, j = 0;
while(left <= right && top <= bottom ){
}
//空间复杂度Onm
时间复杂度Onm
时间复杂度:O(num)
空间复杂度:O(num)