/*
给你一个按 非递减顺序 排序的整数数组 nums,
返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
*/
//可以先赋值,之后快排解决,时间复杂度为O(n + nlog n)
class Solution {
public int[] sortedSquares(int[] nums) {
for (int i = 0; i < nums.length; i++) {
nums[i] = nums[i] * nums[i];
}
Arrays.sort(nums);
return nums;
}
}
//双指针方法解决
//最大的元素在两端
class Solution1 {
public int[] sortedSquares(int[] nums) {
int len = nums.length;
int head = 0;
int end = len - 1;
int[] arr = new int[len];
for (int i = len - 1; i >= 0; i--) {
if (nums[head] * nums[head] > nums[end] * nums[end]) {
arr[i] = nums[head] * nums[head];//如果头处的元素大,就把它放到末尾
head++;//head指针向后移动一位
} else {
arr[i] = nums[end] * nums[end];
end--;
}
}
return arr;
}
}
//双指针while循环
//时间复杂度为O(n)
class Solution2 {
public int[] sortedSquares(int[] nums) {
int len = nums.length;
int head = 0;
int end = len - 1;
int index = len - 1;
int[] arr = new int[len];
while (head <= end) {
if (nums[head] * nums[head] > nums[end] * nums[end]) {
arr[index] = nums[head] * nums[head];
head++;
} else {
arr[index] = nums[end] * nums[end];
end--;
}
index--;
}
return arr;
}
}
//再试一种方法:
//小的元素在中间,注意讨论多种情况
class Solution3 {
public int[] sortedSquares(int[] nums) {
int len = nums.length;
int temp1 = -1;
int[] arr = new int[len];
for (int i = 0; i < len; i++) {
if (nums[i] < 0) {
temp1 = i;
} else {
break;
}
}
int temp2 = temp1 + 1;
for (int i = 0; i < len; i++) {
if (temp1 == -1){
arr[i] = nums[temp2] * nums[temp2];
temp2++;
} else if (temp2 == len) {
arr[i] = nums[temp1] * nums[temp1];
temp1--;
} else if (nums[temp1] * nums[temp1] < nums[temp2] * nums[temp2]) {
arr[i] = nums[temp1] * nums[temp1];
temp1--;
}else{
arr[i] = nums[temp2] * nums[temp2];
temp2++;
}
}
return arr;
}
}
//209.长度最小的子数组
//给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,
//并返回其长度。如果不存在符合条件的子数组,返回 0。
//暴力遍历,两次for循环,外层循环遍历数组,内层循环寻找符合要求是子数组,注意把sum和res更新
class Solution4 {
public int minSubArrayLen(int target, int[] nums) {
int sum;
int len = nums.length;
int res = len + 1;
int subLen;
for (int i = 0; i < len; i++) {
sum = 0;
for (int j = i; j < len; j++) {
sum += nums[j];
if (sum >= target){
subLen = j - i + 1;
res = res < subLen ? res : subLen;
break;
}
}
}
if (res == len + 1){
return 0;
}
return res;
}
}
//滑动窗口法
class Solution5 {
public int minSubArrayLen(int target, int[] nums) {
int i = 0;
int sum = 0;
int len = nums.length;
int res = len + 1;
for (int j = 0; j < len; j++) { //使用j来遍历数组
sum += nums[j];
while (sum >= target){ //如果发现sum符合要求
int subLen = j - i + 1; //记录此时子数组的长度
res = Math.min(res, subLen); //更新res
sum -= nums[i++]; //移动滑动窗口的初始位置,并减去对应元素值
}
}
return res = res == len + 1 ? 0 : res; //看是否进入过while,如果没有进入,返回0
}
}
//844. 比较含退格的字符串
/*
给定 s 和 t 两个字符串,当它们分别被输入到空白的文本编辑器后,如果两者相等,返回 true 。# 代表退格字符。
注意:如果对空文本输入退格字符,文本继续为空。
*/
//设计一个方法进行处理,时间复杂度为O(m+n),m和n分别是两个字符串的长度,因为各要遍历一次
//空间复杂度为O(m+n),产生了两个新String
class Solution6 {
public boolean backspaceCompare(String s, String t) {
String s1 = build(s);
String t1 = build(t);
return s1.equals(t1);
}
public String build(String s){
StringBuilder builder = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) != '#'){
builder.append(s.charAt(i));
}else {
if (builder.length() != 0) {
builder.deleteCharAt(builder.length() - 1);
}
}
}
return builder.toString();
}
}
//使用栈进行处理
class Solution7 {
public boolean backspaceCompare(String s, String t) {
Stack s1 = new Stack();
Stack t1 = new Stack();
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) != '#'){
s1.push(s.charAt(i));
}else{
if (!s1.isEmpty()) {
s1.pop();
}
}
}
for (int i = 0; i < t.length(); i++) {
if (t.charAt(i) != '#'){
t1.push(t.charAt(i));
}else{
if (!t1.isEmpty()){
t1.pop();
}
}
}
String ans1 = "";
String ans2 = "";
while (!s1.isEmpty()){
char c = (char) s1.pop();
ans1 += c;
}
while (!t1.isEmpty()){
char c = (char) t1.pop();
ans2 += c;
}
return ans1.equals(ans2);
}
}