Given a string, find the length of the longest substring without repeating characters.
最暴力的解法就是,首先两个for循环表示子字符串起点和终点,在第二个for循环里面判断是否有相同字符,用set比较适合,没有就和最大值进行比较。这个算法时间复杂度n的三次方,肯定没人用的,就不写了。
优化就是用slide window方法,这个方法是一个关于子字符串等比较通用的方法。理论就是首先固定起点,移动终点直到发现第一个重复字符串。此时再来移动起点,一步一步的移动起点就没有很大的意义,应该直接移到重复值得后一位作为起点。画图后会更清晰。上算法
public int lengthOfLongestSubstring(String s) {
int n = s.length(), ans = 0;
int[] index = new int[128]; //使用一个数据记录字符串上一次的位置位置
for (int i = 0, j = 0; j < n; j++) {
i = Math.max(index[s.charAt(j)], i);
ans = Math.max(ans, j - i + 1);
index[s.charAt(j)] = j + 1;
}
return ans;
}
其中每次更新起始位置和字符串的位置。至于这里更新到字符串后一位有时候为了防止初始值0带来的干扰。
这个时间复杂度会降低到O(n)
Given a collection of distinct numbers, return all possible permutations.
直接上代码
public List<List<Integer>> permute(int[] nums) {
if (nums == null || nums.length == 0) return null;
List<List<Integer>> rst = new ArrayList();
List<Integer> list = new ArrayList();
helper(rst, list, nums);
return rst;
}
public void helper(List<List<Integer>> rst, List<Integer> list, int[] nums){
if (list.size() == nums.length) {
rst.add(new ArrayList(list));
return;
}
for (int i = 0; i < nums.length; i++) {
if (!list.contains(nums[i])) {
list.add(nums[i]);
helper(rst, list, nums);
list.remove(list.size()-1);
}
}
}