一、二分法
题目:
给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为
O(log(m + n))。你可以假设 nums1 和 nums2 不会同时为空。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays
看到时间复杂度为log 要求的,就需要先想一想二分法递归实现:
题解思路:两数组中位数二分法题解
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int m = nums1.length;
int n = nums2.length;
if(m>n){
return findMedianSortedArrays(nums2,nums1);
}
int l = 0, h = 2 * m,L1 = 0,L2 = 0,R1 = 0, R2 = 0,c1=0,c2=0;
while(l<=h){
c1 = (l + h)/2;
c2 = m + n -c1;
L1 = (c1 == 0)? Integer.MIN_VALUE : nums1[(c1-1)/2];
R1 = (c1 == 2 * m)? Integer.MAX_VALUE : nums1[c1/2];
L2 = (c2 == 0)? Integer.MIN_VALUE : nums2[(c2-1)/2];
R2 = (c2 == 2 * n)? Integer.MAX_VALUE : nums2[c2/2];
if(L1>R2){
h = c1-1;
}else if(L2>R1){
l = c1+1;
}else{
break;
}
}
return (Math.max(L1,L2)+Math.min(R1,R2))/2.0;
}
}
二、滑动窗口
滑动窗口模板
string minWindow(string s, string t) {
if (s.empty() || t.empty()) return "";
unordered_map<char, int> hash;
for (char tc: t) hash[tc] ++;
int l = 0, r = 0, counter = hash.size();
string ans;
int maxsize = INT_MAX;
while (r < s.size()) {
if (hash[s[r ++]] -- == 1) counter --;
if (counter == 0) {
while (counter == 0) {
if (r - l < maxsize) {
ans = s.substr(l, r - l);
maxsize = r - l;
}
if (hash[s[l ++]] ++ == 0) counter ++;
}
}
}
return ans;
}
三、位运算
给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
for(int i=0;i<(1 << nums.length);i++){
List<Integer> re1 = new ArrayList();
for(int j=0;j<nums.length;j++)
if (((i >> j) & 1) == 1) re1.add(nums[j]);
result.add(re1);
}
return result;
}
}
数组 [1,2,3]
的子集也就是其中的三个元素取与不取的组合。把它想象为二进制的三个 bit 位 1 1 1
,那么从 0 0 0
到 1 1 1
的 8 个数,就构成了所有子集的选取情况。比如 0 0 1
表示取第1个元素,0 1 1
表示取前两个元素。