ダブルポインター
名前が示すように、2つのポインターは
多くの質問をします。一般に2つのモードがあります
。1つはそれぞれ最初から中央までのiとjのポインターで、もう1つはiとjのポインターが
それぞれ2つの部分を横断します。
記事ディレクトリ
1つと2つの数字の合計
(ダブルポインターを説明するために、このトピックは[2,7]を返すように変更されています。
もちろん、元のトピックはハッシュテーブルを使用すると高速になります)
アイデア:
ソート後、ダブルポインターが使用されるため、コード時間の複雑さがO(nlogn)に削減され
ます。iポインターは0から始まり、
jポインターは最後のビットから始まり
ます。iポインターの数値とjポインターの数値の合計がkより大きい場合、j—、
それ以外の場合はi +
コード:
public static int[] twoSum(int[] nums, int target) {
Arrays.sort(nums);
int i=0;
int j=nums.length-1;
while(i<j)
{
if(nums[i]+nums[j]==target)
{
return new int[] {
nums[i],nums[j]};
}
else if(nums[i]+nums[j]>target)
{
j--;
}
else if(nums[i]+nums[j]<target)
{
i++;
}
}
return new int[] {
};
}
2つと3つの数字の合計
アイデア
2つの数値の合計に基づいて問題を実行します。ダブルポインタを使用すると、複雑さをO(n2)に減らすことができます。tポインタを最後の負の数値に
並べ替え
ます
。iポインタはt + 1
から始まり、jポインタは最後のポインタから始まります。
コード
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
int t=0;
List<List<Integer>> a=new ArrayList<>();
if(nums.length==0)
return a;
Arrays.sort(nums);
int q=nums[0];
while(t<nums.length&&nums[t]<0)
{
if(t!=0&&nums[t]==q)
{
t++;
continue;
}
int i=t+1;
int j=nums.length-1;
while(i<j)
{
if(nums[i]+nums[j]==-nums[t])
{
List<Integer> bIntegers=new ArrayList<>();
bIntegers.add(nums[t]);
bIntegers.add(nums[i]);
bIntegers.add(nums[j]);
a.add(bIntegers);
i++;
while(nums[i]==nums[i-1]) i++;
j--;
while(nums[j]==nums[j+1]) j--;
}
else if(nums[i]+nums[j]<-nums[t])
{
i++;
while(nums[i]==nums[i-1]) i++;
}
else {
j--;
while(nums[j]==nums[j+1]) j--;
}
}
q=nums[t];
t++;
}
return a;
}
}
#トピック順序付けられた配列の3つの正方形
アイデア:
アレイの両端からそれぞれ開始するダブルポインターiとjを使用して、iは負の部分をトラバースし、jはポジティブ部分をトラバースし、ダブルポインターを組み合わせて目的のアレイを合成します。
コード:
class Solution {
public int[] sortedSquares(int[] A) {
int[] nums=new int[A.length];
int i=0;
int j=A.length-1;
int q=nums.length-1;
while(i<=j)
{
int a=(int) Math.pow(A[i], 2);
int b=(int) Math.pow(A[j], 2);
if(a>=b)
{
nums[q]=a;
i++;
}
else {
nums[q]=b;
j--;
}
q--;
}
return nums;
}
}
トピック4は雨を降らせる
アイデア:
この質問は素晴らしいです!
私は長い間考えていましたが、
この質問を理解するに
は、まずその本質を理解し
、次に2つのポインターを実際の計算形式と組み合わせて計算を実現する方法を理解する必要があると思います。
物質:
蓄積された雨の量を決定するものは何ですか?
ポイント-min(左側の最も高い壁と右側の最も高い壁)の壁の高さ
が正の場合、それはこのポイントで蓄積された雨の量を表します
ダブルポインター:
アレイの両側から中央に移動するように2つのポインターiとjを設定します
。1つのポイントのストレージ降雨量を決定できると、ポインターは次の位置に移動します。
保存降雨量はいつ決定できますか?
ポインタがトラバースしているときに、maxleftにアクセスします。maxrightmaxleft
はポイントiに対して正しい必要がありますが、naxrightは必ずしも正しいとは限りません(トラバースが完了していないため、maxrightはポイントjのmaxrightに対してのみです)。
降雨を保存する本質をもう一度確認します。
ポイント
iのmaxleft <maxrightの場合、ポイントiの降雨量はmaxleftで決定できます。
ポイントjの場合、maxright <maxleftの場合、ポイントj
の降雨量はmaxrightで決定できます。
コード:
class Solution {
public int trap(int[] height) {
int sum=0;
int maxleft=0;
int maxright=0;
int i=0;
int j=height.length-1;
while(i<=j)
{
if(maxleft<=maxright)
{
if(maxleft-height[i]>0)
{
sum=sum+maxleft-height[i];
}
if(height[i]>maxleft)
{
maxleft=height[i];
}
i++;
}
else {
if(maxright-height[j]>0)
{
sum=sum+maxright-height[j];
}
if(height[j]>maxright)
{
maxright=height[j];
}
j--;
}
}
return sum;
}
}