算法思想:
暴力解法---》找特性---》是否单调???---》优化
Leetcode题目
以下为Java代码的实现:
class Solution {
public int[] twoSum(int[] numbers, int target) {
int[] res = {-1,-1}; //保存下标
int left = 0; //左下标
int right = numbers.length-1; //右下标
while(left<right) {
if(numbers[left]+numbers[right] == target) {
res[0] = left+1;
res[1] = right+1;
break;
} else if(numbers[left]+numbers[right]>target) {
right--;
} else
left++;
}
return res;
}
}
以下为Java代码:
class Solution {
//每次将nums1、nums2中选出最大值 放在nums1的尾部 注意:指针变化
public void merge(int[] nums1, int m, int[] nums2, int n) {
int curMax = nums1.length-1; //表示当前nums1和nums2数组中的最大值
int nums1Max = m-1; //当前nums1中的最大值
int nums2Max = n-1; //当前nums2中的最大值
while(nums1Max >=0 && nums2Max >=0) {
if(nums1[nums1Max]>nums2[nums2Max]) {
nums1[curMax] = nums1[nums1Max];
nums1Max--;
} else {
nums1[curMax] = nums2[nums2Max];
nums2Max--;
}
curMax--;
}
//表示当nums2中还存在元素
while(nums2Max >=0) {
nums1[curMax] = nums2[nums2Max];
curMax--;
nums2Max--;
}
}
}
以下为Java代码实现:
class Solution {
public int removeDuplicates(int[] nums) {
int save = 0; //该指针记录当前不重复的最大位置
int cur = 1; //遍历数组的指针
while(cur<nums.length) {
if(nums[cur]==nums[save]) {
//表示重复 不用保存 继续往后遍历数组
cur++;
} else {
//表示不重复 那么当前的这个数需要保存下来
save++;
nums[save] = nums[cur];
cur++;
}
}
return save+1;
}
}
这道题需要使用到滑动窗口算法,思想也是基于指针的。
滑动窗口算法思想:
1、在字符串 S 中使用双指针中的左右指针技巧,初始化 left = right = 0,把索引闭区间 [left, right] 称为一个「窗口」。
2、先不断地增加 right 指针扩大窗口 [left, right],直到窗口中的字符串符合要求。
3、此时,停止增加 right,转而不断增加 left 指针缩小窗口 [left, right],直到窗口中的字符串不再符合要求。同时,每次增加 left,都要更新一轮结果。
4、重复第 2 和第 3 步,直到 right 到达字符串 S 的尽头。
算法框架:
int left = 0, right = 0; while (right < s.size()) { window.add(s[right]); right++; while (valid) { window.remove(s[left]); left++; } }
以下为Java代码:
class Solution {
public static String minWindow(String s, String t) {
// 使用滑动窗口算法
int left = 0;
int right = 0;
String windows = "";
int minLen = Integer.MAX_VALUE;
int start = -1;
int end = -1;
while (right < s.length() && left <= right) {
// 不断增加窗口 增加right的值
right++;
windows = s.substring(left, right);
// 不断缩小窗口 增加left的值
while (Contains(windows,t)==true && left <= right) {
// 表示当前窗口如果包含了t 那么计算当前窗口的长度
if (windows.length() < minLen) {
minLen = windows.length();
start = left;
end = right;
}
left++;
windows = s.substring(left, right);
}
}
if (start == -1) {
return "";
}
return s.substring(start, end);
}
//判断当前窗口是否包含字符串t
private static boolean Contains(String windows, String t) {
// TODO Auto-generated method stub
boolean flag = true;
List<Character> listWin = new ArrayList<>();
List<Character> listT = new ArrayList<>();
for(int i=0;i<windows.length();i++) {
listWin.add(windows.charAt(i));
}
for(int i=0;i<t.length();i++) {
listT.add(t.charAt(i));
}
int i = 0;
while(i<listT.size()) {
if(listWin.contains(listT.get(i))) {
listWin.remove(listT.get(i));
listT.remove(listT.get(i));
i=0;
} else {
flag = false;
break;
}
}
if(listT.size()!=0) {
flag = false;
}
return flag;
}
}