双指针(滑动窗口)解题---Leetcode

算法思想:

暴力解法---》找特性---》是否单调???---》优化


Leetcode题目

1、167. 两数之和 II - 输入有序数组

以下为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;
    }
}

 2、88. 合并两个有序数组

以下为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--;
        }
    }
}

3、26. 删除有序数组中的重复项

以下为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;
    }
}

 4、76. 最小覆盖子串

这道题需要使用到滑动窗口算法,思想也是基于指针的。

滑动窗口算法思想:

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;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值