题源:https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/
class Solution {
public int findRepeatDocument(int[] documents) {
Map map = new HashMap();
for(int i : documents){
// 判断是否已经存在
if(map.containsKey(i)){
return i;
}
// 不存在则记录到map
map.put(i, 1);
}
// 未找到
return -1;
}
}
class Solution {
public int findRepeatDocument(int[] documents) {
Set set = new HashSet<>();
for(int i : documents){
// 如果添加失败,则说明已经存在该元素,直接返回
if(!set.add(i)){
return i;
}
}
// 未找到
return -1;
}
}
题源:https://leetcode.cn/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof/
class CQueue {
// 操作push元素
private Stack stack1;
// 操作pop元素
private Stack stack2;
public CQueue() {
stack1 = new Stack<>();
stack2 = new Stack<>();
}
public void appendTail(int value) {
// 操作stack1
stack1.push(value);
}
public int deleteHead() {
// 操作stack2
if(!stack2.isEmpty()){
return stack2.pop();
}
// stack2为空,需要进行倒栈
while(!stack1.isEmpty()){
stack2.push(stack1.pop());
}
// 再次操作stack2
if(!stack2.isEmpty()){
return stack2.pop();
}
// 为空的情况
return -1;
}
}
题源:https://leetcode.cn/problems/fei-bo-na-qi-shu-lie-lcof/description/
class Solution {
public int fib(int n) {
if(n<=1){
return n;
}
// n-2值
int p2=0;
// n-1值
int p1=1;
for(int i=2;i<=n;i++){
// int t = (p1+p2)%1000000007;
int t = p1+p2;
p2=p1;
p1=t;
}
return p1;
}
}
题源:https://leetcode.cn/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/description/
class Solution {
public int stockManagement(int[] stock) {
int low = 0;
int high = stock.length - 1;
while(low stock[high]){
// mid在原队列的分割点后面,现在变为现队列的前部(原队列头部现在在其后面),故舍去其前的部分;且mid比high点值大,肯定非最小值,故low可取mid+1,避免low+1=high时死循环
low = mid + 1;
} else if(stock[mid] < stock[high]) {
// mid在原队列的分割点前面,现在变为现队列的后部(原队列头部现在在其前面),故舍去其后部分
high = mid;
} else {
// mid和high位置的值相同,则可能在前,也可能在后,故前后部分都不能舍弃,仅舍去high这个边界点
high = high - 1;
}
}
return stock[low];
}
}
题源:https://leetcode.cn/problems/diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof/
class Solution {
public int[] trainingPlan(int[] actions) {
int head = 0;
int tail = actions.length - 1;
while(true){
// 从头部开始寻找偶数
while(head
题源:https://leetcode.cn/problems/lian-xu-zi-shu-zu-de-zui-da-he-lcof/
class Solution {
public int maxSales(int[] sales) {
int max = sales[0];
int pre = sales[0];
for(int i = 1;i0)
// max[i] = 0+sales[i];(max[i-1]<=0)
int cur=pre>0?pre+sales[i]:sales[i];
if(cur>max){
max = cur;
}
pre=cur;
}
return max;
}
}
题源:https://leetcode.cn/problems/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-lcof/description/
class Solution {
public char dismantlingAction(String arr) {
Map map = new HashMap<>(arr.length());
// 循环一遍,记录是否重复字符
for(char c : arr.toCharArray()){
if(map.containsKey(c)){
map.put(c, false);
} else {
map.put(c, true);
}
}
// 循环一遍,寻找第一个不重复字符
for(char c : arr.toCharArray()){
if(map.get(c)){
return c;
}
}
// 不存在不重复字符
return ' ';
}
}
class Solution {
public char dismantlingAction(String arr) {
// 代表了26个字母表的数组
byte[] charArr = new byte[26];
char[] sc = arr.toCharArray();
byte init = 0;
byte one = 1;
byte more = 2;
for(char c : sc){
// 标记对应字母表位置的记号
charArr[c-'a']=charArr[c-'a']==init?one:more;
}
for(char c : sc){
// 寻找第一个非重复的字母
if(charArr[c-'a']==one){
return c;
}
}
return ' ';
}
}
题源:https://leetcode.cn/problems/zai-pai-xu-shu-zu-zhong-cha-zhao-shu-zi-lcof/description/
class Solution {
public int countTarget(int[] scores, int target) {
// 二分查找
int low = 0;
int high = scores.length - 1;
int targetIndex = -1;
while(low <= high){
int mid = (low + high)/2;
if(scores[mid] == target){
// 找到目标,直接退出
targetIndex = mid;
break;
}
if(scores[mid] < target){
// 目标在mid右侧,舍去mid左侧
low = mid + 1;
} else {
// 目标在mid左侧,舍去mid右侧
high = mid - 1;
}
}
// 未找到目标
if(targetIndex == -1){
return 0;
}
// 进一步二分查找左边界
int tLow = low;
int tHigh = targetIndex;
int leftIndex = -1;
while(true){ // 左边界一定存在,故死循环即可
int mid = (tLow + tHigh)/2;
if(scores[mid] == target){
if(mid==tLow || scores[mid-1]target){
// 找到右边界
rightIndex = mid;
break;
}
// 非右边界,目标在mid右侧,舍去mid左侧
tLow = mid + 1;
} else {
// 只剩target[mid]>target的情况,此时,目标在mid左侧,舍去mid右侧
tHigh = mid - 1;
}
}
return rightIndex - leftIndex + 1;
}
}
题源:https://leetcode.cn/problems/que-shi-de-shu-zi-lcof/
class Solution {
public int takeAttendance(int[] records) {
int low = 0;
int high = records.length - 1;
while(low <= high){
int mid = (low + high)/2;
if(records[mid] != mid){
// 判断是否是分界点
if(mid==0 || records[mid-1] == mid-1){
return mid;
}
// 分界点在mid左侧,舍去mid右侧部分
high = mid - 1;
} else {
// 分界点在mid右侧,舍弃mid左侧部分
low = mid + 1;
}
}
// 没有找到,返回最后1个数,即数组长度
return records.length;
}
}
题源:https://leetcode.cn/problems/he-wei-sde-liang-ge-shu-zi-lcof/description/
class Solution {
public int[] twoSum(int[] price, int target) {
int head = 0;
int tail = price.length-1;
while(head<=tail){
if(price[head] + price[tail] == target){
// 找到目标
return new int[]{price[head], price[tail]};
}
if(price[head] + price[tail] > target){
// 和偏大,前移尾指针
tail--;
} else {
// 和偏小,后移头指针
head++;
}
}
// 未找到
return new int[0];
}
}
题源:https://leetcode.cn/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof/description/
class Solution {
public int[][] fileCombination(int target) {
int head = 1;
int tail = 2;
List> rst = new ArrayList();
while(head one = new ArrayList();
for(int i=head;i<=tail;i++){
one.add(i);
}
rst.add(one);
head++;
}
if(sum>target){
// 和偏大,后移head指针
head++;
} else {
// 和偏小,后移tail指针
tail++;
}
}
// 组装答案
int[][] rstArr = new int[rst.size()][];
int i = 0;
for(List one : rst){
int[] oneArr = one.stream().mapToInt(Integer::intValue).toArray();
rstArr[i++] = oneArr;
}
return rstArr;
}
}
题源:https://leetcode.cn/problems/fan-zhuan-dan-ci-shun-xu-lcof/description/
class Solution {
public String reverseMessage(String message) {
int start = message.length() - 1;
int end = message.length() - 1;
StringBuilder sb = new StringBuilder();
while(true){
// 先end指针寻找单词结尾
while(end>=0 && message.charAt(end) == ' '){
end--;
}
if(end<0){
// 未找到,结束
return sb.length()>0?sb.deleteCharAt(sb.length()-1).toString():"";
}
// 再start指针寻找单词开始
start = end;
while(start>=0 && message.charAt(start) != ' '){
start--;
}
// 记录单词,即[start-1,end]
sb.append(message.substring(start+1, end+1));
sb.append(' ');
// 将end移动到下一次寻找为止
end = start;
}
}
}
题源:https://leetcode.cn/problems/two-sum/description/
class Solution {
public int[] twoSum(int[] nums, int target) {
Map map = new HashMap<>();
// 循环时边查询是否存在匹配的,边插入
for(int i=0;i
题源:https://leetcode.cn/problems/shu-zu-zhong-de-ni-xu-dui-lcof/
class Solution {
// 逆序计数
private int count;
public int reversePairs(int[] record) {
count = 0;
sortMerge(record);
return count;
}
private int[] sortMerge(int[] record){
int len = record.length;
// 出口
if(len <= 1){
return record;
}
// 拆分2部分分别进行归并排序
int mid = len/2;
int[] sorted1 = sortMerge(Arrays.copyOfRange(record, 0, mid));
int[] sorted2 = sortMerge(Arrays.copyOfRange(record, mid, len));
// 逆序合并2个有序数组
int i = 0;
int j = 0;
int cur = 0;
int[] merged = new int[len];
while(isorted2[j]){
// 在逆序合并中,当前情况说明sorted1当前元素比sorted2中剩余的所有元素都大,而sorted1在原数组中位于sorted2前面,故sorted2中剩余的元素个数即为逆序对个数
count += len - mid - j;
merged[cur++] = sorted1[i++];
} else {
merged[cur++] = sorted2[j++];
}
}
// 处理剩余的部分
while(i
题源:https://leetcode.cn/problems/ba-shu-zu-pai-cheng-zui-xiao-de-shu-lcof/
class Solution {
public String crackPassword(int[] password) {
List list = new ArrayList<>();
// 将数字转换为字符串
for(int i : password){
list.add(String.valueOf(i));
}
// 对字符串列表排序,然后拼接为字符串
// 不使用字符串自然序比较,是因为类似3和30这种情况下会出错。
return list.stream().sorted((s1, s2)->(s1+s2).compareTo(s2+s1)).collect(Collectors.joining(""));
}
}
题源:https://leetcode.cn/problems/zui-chang-bu-han-zhong-fu-zi-fu-de-zi-zi-fu-chuan-lcof/description/
class Solution {
public int dismantlingAction(String arr) {
if(arr.length() <= 1){
return arr.length();
}
int max = 1;
Set set = new HashSet<>();
int head = 0;
int tail = 1;
set.add(arr.charAt(0));
while(tail < arr.length()){
// 判断当前tail是否存在于当前窗口中
if(!set.add(arr.charAt(tail))){
// 添加失败,说明当前值已经在窗口中存在。需要将head前移,直至该值移出窗口
// 先统计当前窗口的长度,更新max记录
if(set.size()>max){
max = set.size();
}
while(arr.charAt(head) != arr.charAt(tail)){
set.remove(arr.charAt(head));
head++;
}
head++;
}
// 继续扩大窗口
tail++;
}
// 统计当前窗口的长度,更新max记录
if(set.size()>max){
max = set.size();
}
return max;
}
}
class Solution {
public int lengthOfLongestSubstring(String s) {
if(s.length() <= 1){
return s.length();
}
int max = 1;
// map存储元素和其下标,不做删除,故需要和窗口的左边界比较判断是否在窗口内
Map map = new HashMap<>();
int head = 0;
int tail = 1;
map.put(s.charAt(0), 0);
while(tail < s.length()){
// 判断当前tail是否存在于当前窗口中
if(map.containsKey(s.charAt(tail)) && map.get(s.charAt(tail))>=head){
// 当前值已经在窗口中存在。需要将head前移至重复的元素的下一个位置
// 先统计当前窗口的长度,更新max记录
if(tail-head>max){
max = tail-head;
}
head=map.get(s.charAt(tail))+1;
// 更新重复元素的新坐标
map.put(s.charAt(tail), tail);
} else {
// 添加元素
map.put(s.charAt(tail), tail);
}
// 继续扩大窗口
tail++;
}
// 统计当前窗口的长度,更新max记录
if(tail-head>max){
max = tail-head;
}
return max;
}
}
// 动态规划方法
class Solution {
public int dismantlingAction(String arr) {
if(arr.length() <= 1){
return arr.length();
}
int max = 1;
// 动态规划
// 设max[i]表示以i位置结尾的最长不重复字符串,则:
// max[0]=第一个字符;
// max[i]=max[i-1]+当前字符;(max[i-1]不包含当前字符)
// max[i]=max[i-1]中当前字符之后的部分+当前字符;(max[i-1]包含当前字符)
// 实际不需要保存max[],只需要保存前值即可
String pre = arr.substring(0,1);
for(int i=1;i max){
max = pre.length();
}
}
return max;
}
}
题源:https://leetcode.cn/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof/description/
class Solution {
public int[] sockCollocation(int[] sockets) {
// 先对所有值进行异或
int s = 0;
for(int i : sockets){
s=s^i;
}
// 对s的2进制寻找1个为1的位,该位为1说明2个目标数字在该位的值不同,故依据该位对所有值分为2组,2个目标数字必然各在1个组内1
int bit = 0x1;
while((s & bit)==0){
bit = bit << 1;
}
// bit即对应位为1,使用其来进行分组
int group1 = 0;
int group2 = 0;
for(int i : sockets){
if((i & bit) == 0){
// 对应位为0,分到1组,直接进行累加异或
group1=group1^i;
} else {
// 对应位为1,分到2组,直接进行累加异或
group2=group2^i;
}
}
// 根据异或性质,累加异或后,group1和group2就只剩不同的值了,即目标数字
return new int[]{group1, group2};
}
}
题源:https://leetcode.cn/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-ii-lcof/description/