977. 有序数组平方
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
# sqare
for i in range(0,len(nums)):
nums[i] = nums[i] * nums[i]
#
for i in range(0, len(nums)-1):
for j in range(i+1, len(nums)):
if nums[i] > nums[j]:
t = nums[j]
nums[j] = nums[i]
nums[i] = t
return nums
直接暴力解题,排序算法 o ( n 2 ) o(n^2) o(n2),超出时间限制。
双指针法
两头遍历,从最大赋值
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
lens = len(nums)
result = [0]*lens
left, right = 0, lens - 1
k = right
while left <= right:
if nums[left] * nums[left] > nums[right] * nums[right]:
result[k] = nums[left] * nums[left]
left += 1
else:
result[k] = nums[right] * nums[right]
right -= 1
k -= 1
return result
209 长度最小的子数组
暴力解题:超时
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int minl = nums.length + 1;
for(int i = 0; i < nums.length; i++){
int sum = nums[i];
if(i == nums.length - 1 && nums[i] < target){
break;
}else if(nums[i] >= target){
return 1;
}
for(int j = i + 1; j < nums.length; j++){
sum += nums[j];
if(sum >= target && (j-i+1) < minl){
minl = j-i+1;
}
}
}
if(minl == nums.length + 1){
return 0;
}
return minl;
}
}
提交版本2:改成滑动窗口法,还超时?错误。
这里并不是正确的滑动窗口,滑动窗口中的前后指针都只往前走。还是枚举。
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int fast = 0;
int slow = 0;
int result = nums.length+1;
for(slow = 0; slow < nums.length; slow++){
int sum = nums[slow];
fast = slow;
boolean ok = false;
while(sum < target){
if(fast >= nums.length - 1){
break;
}
fast++;
sum += nums[fast];
}
if(sum >= target && (fast - slow+1)< result){
result = fast-slow+1;
}
}
if(result == nums.length + 1){
return 0;
}
return result;
}
}
滑动窗口
一个for循环里做两个for循环里的事情;一个起始位置,一个终止位置;
如果for循环里是起始位置,则与暴力法相同;for循环里应是终止位置,动态调整里面的起始位置,控制集合的和。
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int start = 0;
int end = 0;
int sum = 0;
int result = Integer.MAX_VALUE;
for(end = 0; end < nums.length; end++){
sum += nums[end];
while(sum >= target){
int subL = end - start +1;
result = Math.min(subL, result);
sum -= nums[start];
start ++;
}
}
if(result == Integer.MAX_VALUE){
return 0;
}
return result;
}
}
59 螺旋矩阵2
给你一个正整数 n
,生成一个包含 1
到 n2
所有元素,且元素按顺时针顺序螺旋排列的 n x n
正方形矩阵 matrix
。
提交版本1: 写四个方向的移动,通过,但调试较久,且代码冗余。
class Solution {
public int[][] generateMatrix(int n) {
int[][] directs = {{0,1},{1,0},{0,-1},{-1,0}};
int direct = 0;
int[][] result = new int[n][n];
int all = n*n;
int i = 0;
int j = 0;
for(int id = 1; id<=all; id++){
if(result[i][j] ==0){
result[i][j] = id;
}else{
// 当前方向下的新坐标
int new_i = i+directs[direct][0];
int new_j = j+directs[direct][1];
if(new_i>=n || new_j>=n || new_i<0 || new_j<0){
direct = (++direct)%4;
new_i = i+directs[direct][0];
new_j = j+directs[direct][1];
}
if(result[new_i][new_j] == 0){
result[new_i][new_j] = id;
}else{
direct = (++direct)%4;
new_i = i+directs[direct][0];
new_j = j+directs[direct][1];
if(result[new_i][new_j] == 0){
result[new_i][new_j] = id;
}else{
break;
}
}
i = new_i;
j = new_j;
}
}
return result;
}
}
提交版本2: 模拟矩阵后,按照数量填充,左闭右开。
class Solution {
public int[][] generateMatrix(int n) {
int loop = n-1;
int count = 1;
int startx = 0;
int starty = 0;
int[][] result = new int[n][n];
int offset = 0;
while(loop > 0){
int i = startx;
int j = starty;
for(j= starty; j<n-offset-1;j++){
result[startx][j] = count++;
}
//横条
for(i = startx; i<n-offset-1; i++){
result[i][j] = count++;
}
//竖条
for(;j>starty;j--){
result[i][j] = count++;
}
//下条
for(;i>startx;i--){
result[i][j] = count++;
}
//左条
offset ++;
startx ++;
starty ++;
loop -= 2;
}
if(loop == 0){
result[startx][starty] = count++;
}
return result;
}
}
数组总结
Java的二维数组在内存中不是 3*4
的连续地址空间,而是四条连续的地址空间组成!
二分法
- 二分法时间复杂度:O(logn)
双指针法
通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。
滑动窗口
滑动窗口的精妙之处在于根据当前子序列和大小的情况,不断调节子序列的起始位置。从而将O(n^2)的暴力解法降为O(n)。
模拟行为
循环不变量原则