Li Kou アルゴリズムの 1 問目、2 問目、3 問目

目次

最初の問題 (2 つの数値の合計)

問題の説明

問題解決のアイデア:

コード例

2 番目の質問 (2 つの数字を足す)

問題の説明

問題解決のアイデア

コード例

質問 3 (繰り返し文字を含まない最長の部分文字列)

問題の説明

問題解決のアイデア

コード例

 


最初の問題 (2 つの数値の合計)

問題の説明

問題解決のアイデア:

ハッシュ ルックアップの時間計算量は O(1) であるため、ハッシュ コンテナ マップを使用して時間計算量を削減できます。
配列 nums を走査します。i は現在の添え字であり、各値によって target-nums[i] のキー値がマップ内に存在するかどうかが決まります。
存在する場合は 2 つの値が見つかり、存在しない場合は現在の (nums[i],i) をマップに保存し、見つかるまで走査を続けます。
最終的に結果が得られなかった場合は、例外がスローされます。

最終的な時間計算量は o(n) です

コード例

class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer,Integer> map=new HashMap<>();
        for(int i=0;i<nums.length;i++){
            if(map.containsKey(target-nums[i])){
                return new int[] {map.get(target-nums[i]),i};
            }
            map.put(nums[i],i);
        }
        throw new IllegalArgumentException("No two sum solution");
    }
}

HashMap の使用法: Java HashMap | 初心者向けチュートリアル

2 番目の質問 (2 つの数字を足す)

問題の説明

2 つの非負の整数を表す 2 つの空ではないリンク リストが与えられます。それぞれは逆の順序で格納され、各ノードは 1 桁のみを格納できます。

2 つの数値を加算し、その合計を同じ形式で表すリンク リストを返してください。

どちらの数字もゼロ以外のゼロで始まるとは考えられません。

 

問題解決のアイデア

まず第一に、私の sum 関数は、問題を解決するために必要なアルゴリズムです。sum 変数はキャリーまたは現在の合計です。(キャリーとアンドを分離することも可能です)。

次に、結果を保存するものとして新しいリストノード l3 を作成します。

次に、それを l (C 言語のポインターの概念に相当) に割り当てます。ここでは、l を操作することで最終的にデータセットを取得します。ここでは、l3 を先頭ポインター (リンクされたリストの最初のノードを参照) として理解できます。渡された 2 つのリンク リストの 1 つが空でない場合、アルゴリズム ループが実行されます。次の値を見つけます。リンクされたリストに十分な桁がない場合は、自動的に 0 が埋められます。両方が空の場合は、前の合計にキャリーがあるかどうかを確認してから処理します。

コード例

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    int sum=0;
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode l=sum(l1,l2);
        return l;
    }
    public ListNode sum(ListNode l1,ListNode l2){
        ListNode l3=new ListNode();
        ListNode l=l3;
        while(l1!=null||l2!=null){
            if(l1==null){
                l1=new ListNode(0);
            }
            if(l2==null){
                l2=new ListNode(0);
            }
            sum=sum+l1.val+l2.val;
            if(sum>9){
                l.next=new ListNode(sum%10);
                sum=1;
            }else{
                l.next=new ListNode(sum);
                sum=0;
            }
            l1=l1.next;
            l2=l2.next;
            l=l.next;
        }
        if(sum>0){
            l.next=new ListNode(sum);
        }
        return l3.next;
        
    }
}

質問 3 (繰り返し文字を含まない最長の部分文字列)

問題の説明

文字列を指定して s 、 繰り返し文字を含まない最長の部分文字 列の長さを見つけます。

問題解決のアイデア

キュー機能を実装する LinkedList は、ここで使用する Java で提供されています。

まず、処理を容易にするために文字列を文字配列に変換します。temp は一時的な非反復部分文字列の最大長です。

そして、キューに追加する文字があれば、キューの長さがtempより大きいかどうかを判定して処理を行い、キュー内の文字とその文字が等しくなるまでキューをデキューします。

ループ終了後、キューの長さと温度を再度判断します。最後に、非反復文字の最大長を見つけます。

コード例

class Solution {
    public int lengthOfLongestSubstring(String s) {
        char str[]=s.toCharArray();
        int temp=0;
        LinkedList<Character> linked = new LinkedList<>();
        for(int i=0;i<str.length;i++){
            if(linked.contains(str[i])){
                if(temp<linked.size()){
                    temp=linked.size();
                }
                while(linked.removeFirst()!=str[i]){
                }
            }
            linked.add(str[i]);
        }
        if(temp<linked.size()){
            temp=linked.size();
        }
        return temp;
    }
}

 

おすすめ

転載: blog.csdn.net/weixin_53011574/article/details/126943469