对于数组,Java里面也有,int[] nums。
如何求长度:nums.length。
相关知识点:https://www.runoob.com/java/java-array.html
HashMap:https://www.runoob.com/java/java-hashmap.html
注意right的取值,区间是闭是开。
class Solution {
public int removeElement(int[] nums, int val) {
// 快慢指针
int slowIndex = 0;
for (int fastIndex = 0; fastIndex < nums.length; fastIndex++) {
if (nums[fastIndex] != val) {
nums[slowIndex] = nums[fastIndex];
slowIndex++;
}
}
return slowIndex;
}
}
class Solution {
public int[] sortedSquares(int[] nums) {
int n = nums.length;
int[] ans = new int[n];
for (int i = 0, j = n - 1, pos = n - 1; i <= j;) {
if (nums[i] * nums[i] > nums[j] * nums[j]) {
ans[pos] = nums[i] * nums[i];
++i;
} else {
ans[pos] = nums[j] * nums[j];
--j;
}
--pos;
}
return ans;
}
}
有固定窗口大小,和变长窗口两种。
- 我们在字符串 S 中使用双指针中的左右指针技巧,初始化 left = right = 0,把索引闭区间 [left, right]称为一个「窗口」。
- 我们先不断地增加 right 指针扩大窗口 [left, right],直到窗口中的字符串符合要求(包含了T中的所有字符)。
- 此时,我们停止增加 right,转而不断增加 left 指针缩小窗口 [left,right],直到窗口中的字符串不再符合要求(不包含 T 中的所有字符了)。同时,每次增加 left,我们都要更新一轮结果。
- 重复第2和第3步,直到 right 到达字符串 S 的尽头
滑动窗口知识点
class Solution {
public int search(int[] nums, int target) {
// 避免当 target 小于nums[0] nums[nums.length - 1]时多次循环运算
if (target < nums[0] || target > nums[nums.length - 1]) {
return -1;
}
int left = 0, right = nums.length - 1;//right=nums.length时,while是<,right=mid
while (left <= right) {
int mid = left + ((right - left) >> 1);//位运算显然更快一些,也更高级。
if (nums[mid] == target)
return mid;
else if (nums[mid] < target)
left = mid + 1;
else if (nums[mid] > target)
right = mid - 1;
}
return -1;
}
}
class Solution {
public int searchInsert(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while (left <= right) {
int mid = left + ((right - left) >> 1);
if (nums[mid] == target)
return mid;
else if (nums[mid] < target)
left = mid + 1;
else if (nums[mid] > target)
right = mid - 1;
}
return left;
}
}
class Solution {
public int[] searchRange(int[] nums, int target) {
if (nums.length==0||target < nums[0] || target > nums[nums.length - 1]) {
return new int[]{-1, -1};
}
int left = 0, right = nums.length - 1;
while (left <= right) {
int mid = left + ((right - left) >> 1);
if (nums[mid] == target){
int l=mid-1, r=mid+1;
for(int i=mid-1; i>=0; i--){
if(nums[l]==target) l--;
}
for(int i=mid+1; i<nums.length; i++){
if(nums[r]==target) r++;
}
return new int[]{l+1, r-1};
}
else if (nums[mid] < target)
left = mid + 1;
else if (nums[mid] > target)
right = mid - 1;
}
return new int[]{-1, -1};
}
}
转化思路k*k==x
class Solution {
public int mySqrt(int x) {
int l = 0, r = x, ans = -1;
while (l <= r) {
int mid = l + (r - l) / 2;
if ((long) mid * mid <= x) {
ans = mid;
l = mid + 1;
} else {
r = mid - 1;
}
}
return ans;
}
}
谨记用long,因为相乘可能会过大超过int可表示的范围。
class Solution {
public boolean isPerfectSquare(int num) {
if(num==1){
return true;
}
int left=1, right=num-1;
while(left<=right){
int mid = left + ((right - left) >> 1);
System.out.print(mid+" ");
if((long)mid*mid==num){
return true;
}else if((long)mid*mid<num){
left=mid+1;
}else if((long)mid*mid>num){
right=mid-1;
}
}
return false;
}
}
暴力解法
class Solution {
public int removeElement(int[] nums, int val) {
int size = nums.length;
for (int i = 0; i < size; i++) {
if (nums[i] == val) {
for (int j = i + 1; j < size; j++) {
nums[j - 1] = nums[j];
}
i--;
size--;
}
}
return size;
}
}
快慢指针
class Solution {
public int removeElement(int[] nums, int val) {
// 快慢指针
int slowIndex = 0;
for (int fastIndex = 0; fastIndex < nums.length; fastIndex++) {
if (nums[fastIndex] != val) {
nums[slowIndex] = nums[fastIndex];
slowIndex++;
}
}
return slowIndex;
}
}
相向双指针法:元素的顺序可以改变
/**
* 相向双指针方法,基于元素顺序可以改变的题目描述改变了元素相对位置,确保了移动最少元素
* 时间复杂度:O(n)
* 空间复杂度:O(1)
*/
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int leftIndex = 0;
int rightIndex = nums.size() - 1;
while (leftIndex <= rightIndex) {
// 找左边等于val的元素
while (leftIndex <= rightIndex && nums[leftIndex] != val){
++leftIndex;
}
// 找右边不等于val的元素
while (leftIndex <= rightIndex && nums[rightIndex] == val) {
-- rightIndex;
}
// 将右边不等于val的元素覆盖左边等于val的元素
if (leftIndex < rightIndex) {
nums[leftIndex++] = nums[rightIndex--];
}
}
return leftIndex; // leftIndex一定指向了最终数组末尾的下一个元素
}
};
跟上一题按理来说,思路应该是一样的。
先暴力。
class Solution {
public int removeDuplicates(int[] nums) {
int size=nums.length;
for(int i=1; i<size; i++){
if(nums[i]==nums[i-1]){
size--;
for(int j=i; j<nums.length; j++){
nums[j-1]=nums[j];
}
i--;
}
}
return size;
}
}
快慢指针
class Solution {
public int removeDuplicates(int[] nums) {
// 快慢指针
int slowIndex = 0;
for (int fastIndex = 0; fastIndex < nums.length; fastIndex++) {
if (nums[fastIndex] != nums[slowIndex]) {
nums[++slowIndex] = nums[fastIndex];
}
}
// for(int i=0; i
// System.out.print(nums[i]+" ");
// }
return slowIndex+1;
}
}
class Solution {
public void moveZeroes(int[] nums) {
// 快慢指针
int slowIndex = 0;
for (int fastIndex = 0; fastIndex < nums.length; fastIndex++) {
if (nums[fastIndex] != 0) {
nums[slowIndex] = nums[fastIndex];
slowIndex++;
}
}
for(int i=slowIndex; i>=0&&i<nums.length; i++){
nums[i]=0;
}
}
}
class Solution {
public boolean backspaceCompare(String S, String T) {
int i = S.length() - 1, j = T.length() - 1;
int skipS = 0, skipT = 0;
while (i >= 0 || j >= 0) {
while (i >= 0) {
if (S.charAt(i) == '#') {
skipS++;
i--;
} else if (skipS > 0) {
skipS--;
i--;
} else {
break;
}
}
while (j >= 0) {
if (T.charAt(j) == '#') {
skipT++;
j--;
} else if (skipT > 0) {
skipT--;
j--;
} else {
break;
}
}
if (i >= 0 && j >= 0) {
if (S.charAt(i) != T.charAt(j)) {
return false;
}
} else {
if (i >= 0 || j >= 0) {
return false;
}
}
i--;
j--;
}
return true;
}
}
Array包装类。
class Solution {
public int[] sortedSquares(int[] nums) {
int[] ans = new int[nums.length];
for (int i = 0; i < nums.length; ++i) {
ans[i] = nums[i] * nums[i];
}
Arrays.sort(ans);//利用Array这个包装类来处理。
return ans;
}
}
双指针
class Solution {
public int[] sortedSquares(int[] nums) {
int left=0, right=nums.length-1, ans=nums.length-1;
int[] ansNums= new int[nums.length];
while(left<=right){
if(nums[left]*nums[left]>nums[right]*nums[right]){
ansNums[ans] = nums[left]*nums[left];
ans--;
left++;
}else{
ansNums[ans] = nums[right]*nums[right];
ans--;
right--;
}
}
return ansNums;
}
}
整个思路就是先让right大胆地去搜索,之后让left去收敛。
class Solution {
public int minSubArrayLen(int target, int[] nums) {
if(nums.length==0){
return 0;
}
int left=0, right=0;
int sum=0;
int res=100000+5;
for(;right<nums.length;right++){
sum += nums[right];
while(sum>=target){
res = Math.min(res, right-left+1);
sum -= nums[left];
left++;
}
}
return res==100000+5? 0:res;
}
}
用到了HashMap!
class Solution {
public int totalFruit(int[] fruits) {
int n = fruits.length;
Map<Integer, Integer> cnt = new HashMap<Integer, Integer>();
int left = 0, ans = 0;
for (int right = 0; right < n; ++right) {
cnt.put(fruits[right], cnt.getOrDefault(fruits[right], 0) + 1);
while (cnt.size() > 2) {
cnt.put(fruits[left], cnt.get(fruits[left]) - 1);
if (cnt.get(fruits[left]) == 0) {
cnt.remove(fruits[left]);
}
++left;
}
ans = Math.max(ans, right - left + 1);
}
return ans;
}
}
太难了。
class Solution {
Map<Character, Integer> ori = new HashMap<Character, Integer>();
Map<Character, Integer> cnt = new HashMap<Character, Integer>();
public String minWindow(String s, String t) {
int tLen = t.length();
for (int i = 0; i < tLen; i++) {
char c = t.charAt(i);
ori.put(c, ori.getOrDefault(c, 0) + 1);
}
int l = 0, r = -1;
int len = Integer.MAX_VALUE, ansL = -1, ansR = -1;
int sLen = s.length();
while (r < sLen) {
++r;
if (r < sLen && ori.containsKey(s.charAt(r))) {
cnt.put(s.charAt(r), cnt.getOrDefault(s.charAt(r), 0) + 1);
}
while (check() && l <= r) {
if (r - l + 1 < len) {
len = r - l + 1;
ansL = l;
ansR = l + len;
}
if (ori.containsKey(s.charAt(l))) {
cnt.put(s.charAt(l), cnt.getOrDefault(s.charAt(l), 0) - 1);
}
++l;
}
}
return ansL == -1 ? "" : s.substring(ansL, ansR);
}
public boolean check() {
Iterator iter = ori.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
Character key = (Character) entry.getKey();
Integer val = (Integer) entry.getValue();
if (cnt.getOrDefault(key, 0) < val) {
return false;
}
}
return true;
}
}
class Solution {
public int[][] generateMatrix(int n) {
int[][] res = new int[n][n];
int val=1;
for(int k=0; k<n/2+1; k++){
for(int c=k; c<n-k; c++){
res[k][c] = val;
val++;
}
for(int r=k+1; r<n-k; r++){
res[r][n-k-1] = val;
val++;
}
for(int c=n-k-2; c>=k; c--){
res[n-k-1][c] = val;
val++;
}
for(int r=n-k-2; r>=k+1; r--){
res[r][k] = val;
val++;
}
}
return res;
}
}
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
int n = matrix.length;
int m = matrix[0].length;
int nk=0, mk=0;
List<Integer> res = new ArrayList<Integer>();
for(int val=0; val<n*m; ){
for(int c=mk; c<m-mk&&val<n*m; c++){
res.add(matrix[nk][c]);
val++;
}
for(int r=nk+1; r<n-nk&&val<n*m; r++){
res.add(matrix[r][m-mk-1]);
val++;
}
for(int c=m-mk-2; c>=mk&&val<n*m; c--){
res.add(matrix[n-nk-1][c]);
val++;
}
for(int r=n-nk-2; r>=nk+1&&val<n*m; r--){
res.add(matrix[r][mk]);
val++;
}
nk++;
mk++;
}
return res;
}
}