排序插入位置
Sorted insert position
问题陈述:给定一个排序数组和一个目标值,return 如果找到目标则为索引。如果不是,return 按顺序插入时的索引。
您可以假设数组中没有重复项。
这里有几个例子。
[1,3,5,6], 5 → 2
[1,3,5,6], 2 → 1
[1,3,5,6], 7 → 4
[1,3,5,6], 0 → 0
我的代码:
public class Solution {
public int searchInsert(ArrayList<Integer> a, int b) {
int low = 0, high = a.size()-1;
int mid = (low+high)/2;
int retIndex = mid;
while(low<=high){
if(a.get(mid)<b){
low = mid+1;
mid = (low+high)/2;
retIndex = low;
}
else{
high = mid-1;
mid = (low+high)/2;
if(high<0) retIndex = 0;
else retIndex = high;
}
}
return retIndex;
}
}
但是这段代码有一些缺陷(return在一些 大输入 上少了或多了 1 个索引,放在这里是徒劳的),你可以直接检查 here,我无法弄清楚。谁能指出我的错误?或者这个问题的正确代码是什么?
编辑: 我正在展示它给出意外输出的精确输入。
A : [ 3, 4, 18, 19, 20, 27, 28, 31, 36, 42, 44, 71, 72, 75, 82, 86, 88, 97, 100, 103, 105, 107, 110, 116, 118, 119, 121, 122, 140, 141, 142, 155, 157, 166, 176, 184, 190, 199, 201, 210, 212, 220, 225, 234, 235, 236, 238, 244, 259, 265, 266, 280, 283, 285, 293, 299, 309, 312, 317, 335, 341, 352, 354, 360, 365, 368, 370, 379, 386, 391, 400, 405, 410, 414, 416, 428, 433, 437, 438, 445, 453, 457, 458, 472, 476, 480, 485, 489, 491, 493, 501, 502, 505, 510, 511, 520, 526, 535, 557, 574, 593, 595, 604, 605, 612, 629, 632, 633, 634, 642, 647, 653, 654, 656, 658, 686, 689, 690, 691, 709, 716, 717, 737, 738, 746, 759, 765, 775, 778, 783, 786, 787, 791, 797, 801, 806, 815, 820, 822, 823, 832, 839, 841, 847, 859, 873, 877, 880, 886, 904, 909, 911, 917, 919, 937, 946, 948, 951, 961, 971, 979, 980, 986, 993 ]
B : 902
此输入的预期 returned 值为:149
此输入的代码 returned 值为:148
对于最基本的测试用例,您的代码将失败:
[1,3,5,6], 5 → 2
你应该处理值在中间 a.get(mid) > b
和 a.get(mid)== b
的情况
分别地。你也不需要单独维护一个变量retIndex
。
因此将您的代码更改为:
while(low<=high){
if(a.get(mid)<b){
low = mid+1;
mid = (low+high)/2;
}
else if(a.get(mid) > b){
high = mid-1;
mid = (low+high)/2;
}
else return mid;
}
return low;//handles the case when no match is found.
您需要处理相等性并从更大的分支更改 return。
while(low<=high){
if (a.get(mid) == b) return mid;
else if(a.get(mid)<b){
low = mid+1;
mid = (low+high)/2;
retIndex = low;
}
else {
high = mid-1;
retIndex = mid;
mid = (low+high)/2;
}
}
这个呢?
public class Solution {
public int searchInsert(ArrayList<Integer> a, int b) {
int low = 0;
int high = a.size();
int candidateIdx = (low + high) / 2;
int candidateValue;
int prevCandidateIdx = -1;
while (low != high ) {
candidateValue = a.get(candidateIdx);
if (candidateValue == b) {
break;
} else if (candidateValue < b && prevCandidateIdx == candidateIdx -1) {
candidateIdx++;
break;
} else if (candidateValue < b) {
low = candidateIdx;
} else if (prevCandidateIdx == candidateIdx + 1) {
break;
} else {
high = candidateIdx;
}
prevCandidateIdx = candidateIdx;
candidateIdx = (low + high)/2;
}
return candidateIdx;
}
}
问题陈述:给定一个排序数组和一个目标值,return 如果找到目标则为索引。如果不是,return 按顺序插入时的索引。 您可以假设数组中没有重复项。
这里有几个例子。
[1,3,5,6], 5 → 2
[1,3,5,6], 2 → 1
[1,3,5,6], 7 → 4
[1,3,5,6], 0 → 0
我的代码:
public class Solution {
public int searchInsert(ArrayList<Integer> a, int b) {
int low = 0, high = a.size()-1;
int mid = (low+high)/2;
int retIndex = mid;
while(low<=high){
if(a.get(mid)<b){
low = mid+1;
mid = (low+high)/2;
retIndex = low;
}
else{
high = mid-1;
mid = (low+high)/2;
if(high<0) retIndex = 0;
else retIndex = high;
}
}
return retIndex;
}
}
但是这段代码有一些缺陷(return在一些 大输入 上少了或多了 1 个索引,放在这里是徒劳的),你可以直接检查 here,我无法弄清楚。谁能指出我的错误?或者这个问题的正确代码是什么?
编辑: 我正在展示它给出意外输出的精确输入。
A : [ 3, 4, 18, 19, 20, 27, 28, 31, 36, 42, 44, 71, 72, 75, 82, 86, 88, 97, 100, 103, 105, 107, 110, 116, 118, 119, 121, 122, 140, 141, 142, 155, 157, 166, 176, 184, 190, 199, 201, 210, 212, 220, 225, 234, 235, 236, 238, 244, 259, 265, 266, 280, 283, 285, 293, 299, 309, 312, 317, 335, 341, 352, 354, 360, 365, 368, 370, 379, 386, 391, 400, 405, 410, 414, 416, 428, 433, 437, 438, 445, 453, 457, 458, 472, 476, 480, 485, 489, 491, 493, 501, 502, 505, 510, 511, 520, 526, 535, 557, 574, 593, 595, 604, 605, 612, 629, 632, 633, 634, 642, 647, 653, 654, 656, 658, 686, 689, 690, 691, 709, 716, 717, 737, 738, 746, 759, 765, 775, 778, 783, 786, 787, 791, 797, 801, 806, 815, 820, 822, 823, 832, 839, 841, 847, 859, 873, 877, 880, 886, 904, 909, 911, 917, 919, 937, 946, 948, 951, 961, 971, 979, 980, 986, 993 ]
B : 902
此输入的预期 returned 值为:149
此输入的代码 returned 值为:148
对于最基本的测试用例,您的代码将失败:
[1,3,5,6], 5 → 2
你应该处理值在中间 a.get(mid) > b
和 a.get(mid)== b
的情况
分别地。你也不需要单独维护一个变量retIndex
。
因此将您的代码更改为:
while(low<=high){
if(a.get(mid)<b){
low = mid+1;
mid = (low+high)/2;
}
else if(a.get(mid) > b){
high = mid-1;
mid = (low+high)/2;
}
else return mid;
}
return low;//handles the case when no match is found.
您需要处理相等性并从更大的分支更改 return。
while(low<=high){
if (a.get(mid) == b) return mid;
else if(a.get(mid)<b){
low = mid+1;
mid = (low+high)/2;
retIndex = low;
}
else {
high = mid-1;
retIndex = mid;
mid = (low+high)/2;
}
}
这个呢?
public class Solution {
public int searchInsert(ArrayList<Integer> a, int b) {
int low = 0;
int high = a.size();
int candidateIdx = (low + high) / 2;
int candidateValue;
int prevCandidateIdx = -1;
while (low != high ) {
candidateValue = a.get(candidateIdx);
if (candidateValue == b) {
break;
} else if (candidateValue < b && prevCandidateIdx == candidateIdx -1) {
candidateIdx++;
break;
} else if (candidateValue < b) {
low = candidateIdx;
} else if (prevCandidateIdx == candidateIdx + 1) {
break;
} else {
high = candidateIdx;
}
prevCandidateIdx = candidateIdx;
candidateIdx = (low + high)/2;
}
return candidateIdx;
}
}