記事ディレクトリ
1.上下にリンクする配列内の要素を見つけます
トピックのソース:https://www.nowcoder.com/discuss/478118(Shanghai Douyin Client Development Experience)
ご存知のように、Bytedanceはアルゴリズムの質問に細心の注意を払っており、アルゴリズムはしばしば拒否票になります。夏のインターンシップで、私は3つの側面で最後のアルゴリズムの質問に遭遇したため、最初にインターンシップのオファーを受け取ることができませんでした。。。。
最初にタイトルの説明を見てください。
寻找k:在无序数组中,k的所有左值比它更小,所有右值比他更大。限定o(n)。
この質問は実際には比較的単純です。O(N ^ 2)アルゴリズムがあります(左右の要素が要件を満たしているかどうかを確認するために各要素を1つずつトラバースします)。ただし、配列が少し長い場合、たとえば10w要素の長さは、明らかに、現時点では、上記のアルゴリズムの効率は低すぎます。したがって、O(Nアルゴリズム)が必要です
O(N ^ 2)アルゴリズムでは、選択した要素の後のトラバーサルは、要素の前の最大値と要素の後ろの最小値を見つけることと同じです。要素が前の最大値より大きく、次の最小値より小さい場合、これが必要な値です。実際、毎回前後に最大値と最小値の計算を繰り返す必要はなく、直接保存するだけです。
しかし、それはどのように保存されるべきでしょうか?質問の条件を満たす要素が配列内に複数存在する可能性があるため、2つの値だけを使用して要件を満たすことはできません。したがって、2つの配列を宣言して、配列内の各要素と各要素の前に最大値を格納します。最小値の後、最後に2つの配列をトラバースし、対応する位置要素のサイズを比較します
/**
* 寻找k:在无序数组中,k的所有左值比它更小,所有右值比他更大。限定o(n)。
*/
public class FindBridgeNumber {
@Test
public void test(){
int[] nums={
2,1,2,3,4,4};
List<Integer> result=findBridgeNumber(nums);
System.out.println(result);
}
public List<Integer> findBridgeNumber(int[] nums){
List<Integer> result=new ArrayList<>();
if(nums.length<=2){
return result;
}
int[] dpLeft=new int[nums.length];
dpLeft[0]=Integer.MIN_VALUE;
dpLeft[1]=nums[0];
for (int i=2;i<dpLeft.length;i++){
dpLeft[i]=Math.max(nums[i-1],dpLeft[i-1]);
}
int[] dpRight=new int[nums.length];
dpRight[dpRight.length-1]=Integer.MAX_VALUE;
dpRight[dpRight.length-2]=nums[nums.length-1];
for (int i=dpRight.length-3;i>=0;i--){
dpRight[i]=Math.min(nums[i+1],dpRight[i+1]);
}
for (int i=0;i<nums.length;i++){
if(dpLeft[i]<nums[i]&&dpRight[i]>nums[i]){
result.add(nums[i]);
}
}
return result;
}
}