5557. 最大重复子字符串
题目-5557. 最大重复子字符串
比赛的时候写的超级复杂,最简单的就是一次构造k个重复的word,查查有没有。
class Solution {
public int maxRepeating(String sequence, String word) {
int cnt = 0;
String ss = word;
int n = sequence.length();
int m = word.length();
while (true){
if (ss.length() > n){
break;
}
if (sequence.contains(ss)){
cnt++;
ss = ss + word;
}
else{
break;
}
}
return cnt;
}
}
5558. 合并两个链表
题目-5558. 合并两个链表
获取list1截取位置的前一个节点和后一个节点,list2的最后一个节点,连接即可。
/**
* 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 mergeInBetween(ListNode list1, int a, int b, ListNode list2) {
ListNode cur1 = list1, cur11 = list1, cur2 = list2;
while (cur2.next != null){
cur2 = cur2.next;
}
int cnt = 0;
while (cnt < a - 1){
cur1 = cur1.next;
cnt++;
}
cnt = 0;
while (cnt <= b){
cur11 = cur11.next;
cnt++;
}
cur1.next = list2;
cur2.next = cur11;
return list1;
}
}
5560. 设计前中后队列
题目-5560. 设计前中后队列
维持一个ArrayList,按照要求修改即可
class FrontMiddleBackQueue {
private List<Integer> arr = new ArrayList<>();
public FrontMiddleBackQueue() {
}
public void pushFront(int val) {
arr.add(0, val);
}
public void pushMiddle(int val) {
arr.add(arr.size() / 2, val);
}
public void pushBack(int val) {
arr.add(arr.size(), val);
}
public int popFront() {
if (arr.isEmpty()) return -1;
int val = arr.get(0);
arr.remove(0);
return val;
}
public int popMiddle() {
if (arr.isEmpty()) return -1;
int val = arr.get((arr.size() - 1) / 2);
arr.remove((arr.size() - 1) / 2);
return val;
}
public int popBack() {
if (arr.isEmpty()) return -1;
int val = arr.get(arr.size() - 1);
arr.remove(arr.size() - 1);
return val;
}
}
/**
* Your FrontMiddleBackQueue object will be instantiated and called as such:
* FrontMiddleBackQueue obj = new FrontMiddleBackQueue();
* obj.pushFront(val);
* obj.pushMiddle(val);
* obj.pushBack(val);
* int param_4 = obj.popFront();
* int param_5 = obj.popMiddle();
* int param_6 = obj.popBack();
*/
当然也可以作死,自己去维护一个数组
class FrontMiddleBackQueue {
private int[] arr = new int[1005];
private int length = 0;
public FrontMiddleBackQueue() {
this.length = 0;
}
public void pushFront(int val) {
for (int i = length; i >= 1; i--){
arr[i] = arr[i - 1];
}
arr[0] = val;
length+=1;
}
public void pushMiddle(int val) {
int x = length / 2;
for (int i = length; i > x; i--){
arr[i] = arr[i - 1];
}
arr[x] = val;
length+=1;
}
public void pushBack(int val) {
arr[length] = val;
length ++;
}
public int popFront() {
if (length > 0){
int x = arr[0];
for (int i = 1; i < length; i++){
arr[i - 1] = arr[i];
}
length--;
return x;
}
else{
return -1;
}
}
public int popMiddle() {
if (length <= 0) return -1;
int x = arr[(length - 1) / 2];
for (int i = (length-1) / 2 ; i < length-1; i++){
arr[i] = arr[i+1];
}
length--;
return x;
}
public int popBack() {
if (length <=0) return -1;
length--;
return arr[length];
}
}
/**
* Your FrontMiddleBackQueue object will be instantiated and called as such:
* FrontMiddleBackQueue obj = new FrontMiddleBackQueue();
* obj.pushFront(val);
* obj.pushMiddle(val);
* obj.pushBack(val);
* int param_4 = obj.popFront();
* int param_5 = obj.popMiddle();
* int param_6 = obj.popBack();
*/
再更:这题更优的做法,应该是维护两个双端链表,第一个链表存储0~mid, 第二个存储mid+1 ~ end
这样,在每次添加时,需要额外进行一次检查,来调整left和right的平衡,时间开销为O(1),这样即可将查询中间的时间复杂度从O(n)降至O(1)
class FrontMiddleBackQueue {
private LinkedList<Integer> left;
private LinkedList<Integer> right;
public FrontMiddleBackQueue() {
left = new LinkedList<>();
right = new LinkedList<>();
}
public void pushFront(int val) {
left.addFirst(val);
check();
}
public void pushMiddle(int val) {
if (left.size() - right.size() == 1){
int t = left.peekLast();
left.removeLast();
right.addFirst(t);
}
left.addLast(val);
check();
}
public void pushBack(int val) {
right.addLast(val);
check();
}
public int popFront() {
if (left.size() == 0 && right.size() == 0) return -1;
int val = left.peek();
left.removeFirst();
check();
return val;
}
public int popMiddle() {
if (left.size() == 0 && right.size() == 0) return -1;
int val = left.peekLast();
left.removeLast();
check();
return val;
}
public int popBack() {
if (left.size() == 0 && right.size() == 0) return -1;
int val = -1;
if (right.size() == 0){
val = left.peekLast();
left.removeLast();
}
else{
val = right.peekLast();
right.removeLast();
}
check();
return val;
}
private void check(){
if (left.size() - right.size() > 1){
int t = left.peekLast();
left.removeLast();
right.addFirst(t);
}
else if (right.size() > left.size()){
int t = right.peekFirst();
right.removeFirst();
left.add(t);
}
}
}
/**
* Your FrontMiddleBackQueue object will be instantiated and called as such:
* FrontMiddleBackQueue obj = new FrontMiddleBackQueue();
* obj.pushFront(val);
* obj.pushMiddle(val);
* obj.pushBack(val);
* int param_4 = obj.popFront();
* int param_5 = obj.popMiddle();
* int param_6 = obj.popBack();
*/
5559. 得到山形数组的最少删除次数
题目-5559. 得到山形数组的最少删除次数
求最长上升子序列长度的变种,维护两个数组,一个计算当前点左边有多少比他低的,另一个计算当前点右边有多少比他低的。最后,左右求和取最大。注意,i必须大于0.
class Solution {
public int minimumMountainRemovals(int[] nums) {
int n = nums.length;
int[] dppre = new int[n + 1];
int[] dplast = new int[n + 1];
dppre[0] = 0;
dplast[n - 1] = 0;
for (int i = 1; i < n; i++){
for (int j = 0; j < i; j++){
if (nums[j] < nums[i]){
dppre[i] = Math.max(dppre[i], dppre[j] + 1);
}
}
}
for (int i = n - 2; i >= 0; i--){
for (int j = n - 1; j > i; j--){
if (nums[i] > nums[j]){
dplast[i] = Math.max(dplast[i], dplast[j] + 1);
}
}
}
int maxx = 0;
for (int i = 0; i < n; i++){
if (dppre[i] + dplast[i] > maxx){
if (dppre[i]>0 && dplast[i] >0)
maxx = dppre[i] + dplast[i];
}
}
return n - maxx - 1;
}
}