Given a sorted array with n elements and element x that is inside the array at position k, find k in...












2












$begingroup$



Given a sorted array $A[1,ldots,n]$ and element $x$ that located at
position $k$. We know $x$, we don't know $k$. Write an algorithm that finds $k$, in $O(min(log k, log(n-k))$ time complexity.




Any ideas how to solve this?










share|cite|improve this question











$endgroup$












  • $begingroup$
    Sounds like it wants you to do two exponential searches in parallel, one starting from the beginning and one starting from the end.
    $endgroup$
    – Bergi
    4 hours ago
















2












$begingroup$



Given a sorted array $A[1,ldots,n]$ and element $x$ that located at
position $k$. We know $x$, we don't know $k$. Write an algorithm that finds $k$, in $O(min(log k, log(n-k))$ time complexity.




Any ideas how to solve this?










share|cite|improve this question











$endgroup$












  • $begingroup$
    Sounds like it wants you to do two exponential searches in parallel, one starting from the beginning and one starting from the end.
    $endgroup$
    – Bergi
    4 hours ago














2












2








2





$begingroup$



Given a sorted array $A[1,ldots,n]$ and element $x$ that located at
position $k$. We know $x$, we don't know $k$. Write an algorithm that finds $k$, in $O(min(log k, log(n-k))$ time complexity.




Any ideas how to solve this?










share|cite|improve this question











$endgroup$





Given a sorted array $A[1,ldots,n]$ and element $x$ that located at
position $k$. We know $x$, we don't know $k$. Write an algorithm that finds $k$, in $O(min(log k, log(n-k))$ time complexity.




Any ideas how to solve this?







algorithms time-complexity binary-search






share|cite|improve this question















share|cite|improve this question













share|cite|improve this question




share|cite|improve this question








edited 13 hours ago









xskxzr

3,55011031




3,55011031










asked 15 hours ago









Avishay28Avishay28

1433




1433












  • $begingroup$
    Sounds like it wants you to do two exponential searches in parallel, one starting from the beginning and one starting from the end.
    $endgroup$
    – Bergi
    4 hours ago


















  • $begingroup$
    Sounds like it wants you to do two exponential searches in parallel, one starting from the beginning and one starting from the end.
    $endgroup$
    – Bergi
    4 hours ago
















$begingroup$
Sounds like it wants you to do two exponential searches in parallel, one starting from the beginning and one starting from the end.
$endgroup$
– Bergi
4 hours ago




$begingroup$
Sounds like it wants you to do two exponential searches in parallel, one starting from the beginning and one starting from the end.
$endgroup$
– Bergi
4 hours ago










3 Answers
3






active

oldest

votes


















4












$begingroup$

The basic idea, when we don't know $k$, is to ask for elements with an exponentially growing index.
The most natural here is some use of powers of two.
For example, we can ask for elements with indices $1$, $2$, $4$, $8$, $16$, $dots$.
Or with indices $1$, $3$, $7$, $15$, $31$, $dots$.
This way, it will take $O (log k)$ steps to arrive at the first element greater than $x$.



After we found two boundaries for $k$, do a regular binary search between them.
If we asked for consecutive powers of two, the length of the interval is also $O (k)$, and the binary search will complete in $O (log k)$.



When we know that $n - k$ is small, we can do the same but down from $n$, instead of up from $1$.
That is, first ask for elements at indices $n$, $n - 1$, $n - 3$, $n - 7$, $dots$.
Once we hit an element less than $x$, do a regular binary search between the boundaries we found.



Lastly, what to do when we don't know whether $k$ is small or $n - k$ is small, but want to complete using the fastest of the two?
Just run the searches in parallel.
That is, ask for element $1$, then $n$, then $2$, then $n - 1$, then $4$, then $n - 3$, and so on.
Naturally, either an odd question gives us an element greater than $x$, or an even question gives us an element less than $x$, in $O (log (min (k, n - k)))$.
Proceed then with the regular binary search.






share|cite|improve this answer









$endgroup$





















    4












    $begingroup$

    Check the first element. Then check the last. Then the second, then the second to last, then the fourth, then the fourth to last, then the eighth, and so on. Stop upon bounding the location of x to a region at the front or back of the list.



    Once you've bounded it you can just do a binary search.



    Can you see why this works?






    share|cite|improve this answer









    $endgroup$





















      1












      $begingroup$

      You can apply binary expanding search starting from both ends of the given array.



      For ease of statement, I will assume $n=2^k$ for some integer $kge0$. Otherwise, a boundary check can be included in step 3.1. I will assume the given array is sorted from small to large; otherwise, one comparison between $a_1$ and $a_n$ can be done to find the sorting order and the procedure can be adjusted accordingly.




      1. Check if $x=a_1$ or $x=a_n$. If yes, return 1 or $n$ accordingly and stop.

      2. Let $i=1$.

      3. Loop the following.


        1. Is $xle a_{2^i}$?


          • If yes, do a binary search for $x$ between $a_{2^{i-1}}$ exclusively and $a_{2^i}$ inclusively. Return the index and stop.



        2. Is $xge a_{n-2^i+1}$?


          • If yes, do a binary search for $x$ between $a_{n-2^{i}+1}$ inclusively and $a_{n-2^{i-1}+1}$ exclusively.
            Return the index and stop.



        3. increase $i$ by 1.








      share|cite|improve this answer











      $endgroup$













        Your Answer





        StackExchange.ifUsing("editor", function () {
        return StackExchange.using("mathjaxEditing", function () {
        StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
        StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["$", "$"], ["\\(","\\)"]]);
        });
        });
        }, "mathjax-editing");

        StackExchange.ready(function() {
        var channelOptions = {
        tags: "".split(" "),
        id: "419"
        };
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function() {
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled) {
        StackExchange.using("snippets", function() {
        createEditor();
        });
        }
        else {
        createEditor();
        }
        });

        function createEditor() {
        StackExchange.prepareEditor({
        heartbeatType: 'answer',
        autoActivateHeartbeat: false,
        convertImagesToLinks: false,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: null,
        bindNavPrevention: true,
        postfix: "",
        imageUploader: {
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        },
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        });


        }
        });














        draft saved

        draft discarded


















        StackExchange.ready(
        function () {
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcs.stackexchange.com%2fquestions%2f104291%2fgiven-a-sorted-array-with-n-elements-and-element-x-that-is-inside-the-array-at-p%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        3 Answers
        3






        active

        oldest

        votes








        3 Answers
        3






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        4












        $begingroup$

        The basic idea, when we don't know $k$, is to ask for elements with an exponentially growing index.
        The most natural here is some use of powers of two.
        For example, we can ask for elements with indices $1$, $2$, $4$, $8$, $16$, $dots$.
        Or with indices $1$, $3$, $7$, $15$, $31$, $dots$.
        This way, it will take $O (log k)$ steps to arrive at the first element greater than $x$.



        After we found two boundaries for $k$, do a regular binary search between them.
        If we asked for consecutive powers of two, the length of the interval is also $O (k)$, and the binary search will complete in $O (log k)$.



        When we know that $n - k$ is small, we can do the same but down from $n$, instead of up from $1$.
        That is, first ask for elements at indices $n$, $n - 1$, $n - 3$, $n - 7$, $dots$.
        Once we hit an element less than $x$, do a regular binary search between the boundaries we found.



        Lastly, what to do when we don't know whether $k$ is small or $n - k$ is small, but want to complete using the fastest of the two?
        Just run the searches in parallel.
        That is, ask for element $1$, then $n$, then $2$, then $n - 1$, then $4$, then $n - 3$, and so on.
        Naturally, either an odd question gives us an element greater than $x$, or an even question gives us an element less than $x$, in $O (log (min (k, n - k)))$.
        Proceed then with the regular binary search.






        share|cite|improve this answer









        $endgroup$


















          4












          $begingroup$

          The basic idea, when we don't know $k$, is to ask for elements with an exponentially growing index.
          The most natural here is some use of powers of two.
          For example, we can ask for elements with indices $1$, $2$, $4$, $8$, $16$, $dots$.
          Or with indices $1$, $3$, $7$, $15$, $31$, $dots$.
          This way, it will take $O (log k)$ steps to arrive at the first element greater than $x$.



          After we found two boundaries for $k$, do a regular binary search between them.
          If we asked for consecutive powers of two, the length of the interval is also $O (k)$, and the binary search will complete in $O (log k)$.



          When we know that $n - k$ is small, we can do the same but down from $n$, instead of up from $1$.
          That is, first ask for elements at indices $n$, $n - 1$, $n - 3$, $n - 7$, $dots$.
          Once we hit an element less than $x$, do a regular binary search between the boundaries we found.



          Lastly, what to do when we don't know whether $k$ is small or $n - k$ is small, but want to complete using the fastest of the two?
          Just run the searches in parallel.
          That is, ask for element $1$, then $n$, then $2$, then $n - 1$, then $4$, then $n - 3$, and so on.
          Naturally, either an odd question gives us an element greater than $x$, or an even question gives us an element less than $x$, in $O (log (min (k, n - k)))$.
          Proceed then with the regular binary search.






          share|cite|improve this answer









          $endgroup$
















            4












            4








            4





            $begingroup$

            The basic idea, when we don't know $k$, is to ask for elements with an exponentially growing index.
            The most natural here is some use of powers of two.
            For example, we can ask for elements with indices $1$, $2$, $4$, $8$, $16$, $dots$.
            Or with indices $1$, $3$, $7$, $15$, $31$, $dots$.
            This way, it will take $O (log k)$ steps to arrive at the first element greater than $x$.



            After we found two boundaries for $k$, do a regular binary search between them.
            If we asked for consecutive powers of two, the length of the interval is also $O (k)$, and the binary search will complete in $O (log k)$.



            When we know that $n - k$ is small, we can do the same but down from $n$, instead of up from $1$.
            That is, first ask for elements at indices $n$, $n - 1$, $n - 3$, $n - 7$, $dots$.
            Once we hit an element less than $x$, do a regular binary search between the boundaries we found.



            Lastly, what to do when we don't know whether $k$ is small or $n - k$ is small, but want to complete using the fastest of the two?
            Just run the searches in parallel.
            That is, ask for element $1$, then $n$, then $2$, then $n - 1$, then $4$, then $n - 3$, and so on.
            Naturally, either an odd question gives us an element greater than $x$, or an even question gives us an element less than $x$, in $O (log (min (k, n - k)))$.
            Proceed then with the regular binary search.






            share|cite|improve this answer









            $endgroup$



            The basic idea, when we don't know $k$, is to ask for elements with an exponentially growing index.
            The most natural here is some use of powers of two.
            For example, we can ask for elements with indices $1$, $2$, $4$, $8$, $16$, $dots$.
            Or with indices $1$, $3$, $7$, $15$, $31$, $dots$.
            This way, it will take $O (log k)$ steps to arrive at the first element greater than $x$.



            After we found two boundaries for $k$, do a regular binary search between them.
            If we asked for consecutive powers of two, the length of the interval is also $O (k)$, and the binary search will complete in $O (log k)$.



            When we know that $n - k$ is small, we can do the same but down from $n$, instead of up from $1$.
            That is, first ask for elements at indices $n$, $n - 1$, $n - 3$, $n - 7$, $dots$.
            Once we hit an element less than $x$, do a regular binary search between the boundaries we found.



            Lastly, what to do when we don't know whether $k$ is small or $n - k$ is small, but want to complete using the fastest of the two?
            Just run the searches in parallel.
            That is, ask for element $1$, then $n$, then $2$, then $n - 1$, then $4$, then $n - 3$, and so on.
            Naturally, either an odd question gives us an element greater than $x$, or an even question gives us an element less than $x$, in $O (log (min (k, n - k)))$.
            Proceed then with the regular binary search.







            share|cite|improve this answer












            share|cite|improve this answer



            share|cite|improve this answer










            answered 12 hours ago









            GassaGassa

            655310




            655310























                4












                $begingroup$

                Check the first element. Then check the last. Then the second, then the second to last, then the fourth, then the fourth to last, then the eighth, and so on. Stop upon bounding the location of x to a region at the front or back of the list.



                Once you've bounded it you can just do a binary search.



                Can you see why this works?






                share|cite|improve this answer









                $endgroup$


















                  4












                  $begingroup$

                  Check the first element. Then check the last. Then the second, then the second to last, then the fourth, then the fourth to last, then the eighth, and so on. Stop upon bounding the location of x to a region at the front or back of the list.



                  Once you've bounded it you can just do a binary search.



                  Can you see why this works?






                  share|cite|improve this answer









                  $endgroup$
















                    4












                    4








                    4





                    $begingroup$

                    Check the first element. Then check the last. Then the second, then the second to last, then the fourth, then the fourth to last, then the eighth, and so on. Stop upon bounding the location of x to a region at the front or back of the list.



                    Once you've bounded it you can just do a binary search.



                    Can you see why this works?






                    share|cite|improve this answer









                    $endgroup$



                    Check the first element. Then check the last. Then the second, then the second to last, then the fourth, then the fourth to last, then the eighth, and so on. Stop upon bounding the location of x to a region at the front or back of the list.



                    Once you've bounded it you can just do a binary search.



                    Can you see why this works?







                    share|cite|improve this answer












                    share|cite|improve this answer



                    share|cite|improve this answer










                    answered 12 hours ago









                    Daniel McLauryDaniel McLaury

                    44427




                    44427























                        1












                        $begingroup$

                        You can apply binary expanding search starting from both ends of the given array.



                        For ease of statement, I will assume $n=2^k$ for some integer $kge0$. Otherwise, a boundary check can be included in step 3.1. I will assume the given array is sorted from small to large; otherwise, one comparison between $a_1$ and $a_n$ can be done to find the sorting order and the procedure can be adjusted accordingly.




                        1. Check if $x=a_1$ or $x=a_n$. If yes, return 1 or $n$ accordingly and stop.

                        2. Let $i=1$.

                        3. Loop the following.


                          1. Is $xle a_{2^i}$?


                            • If yes, do a binary search for $x$ between $a_{2^{i-1}}$ exclusively and $a_{2^i}$ inclusively. Return the index and stop.



                          2. Is $xge a_{n-2^i+1}$?


                            • If yes, do a binary search for $x$ between $a_{n-2^{i}+1}$ inclusively and $a_{n-2^{i-1}+1}$ exclusively.
                              Return the index and stop.



                          3. increase $i$ by 1.








                        share|cite|improve this answer











                        $endgroup$


















                          1












                          $begingroup$

                          You can apply binary expanding search starting from both ends of the given array.



                          For ease of statement, I will assume $n=2^k$ for some integer $kge0$. Otherwise, a boundary check can be included in step 3.1. I will assume the given array is sorted from small to large; otherwise, one comparison between $a_1$ and $a_n$ can be done to find the sorting order and the procedure can be adjusted accordingly.




                          1. Check if $x=a_1$ or $x=a_n$. If yes, return 1 or $n$ accordingly and stop.

                          2. Let $i=1$.

                          3. Loop the following.


                            1. Is $xle a_{2^i}$?


                              • If yes, do a binary search for $x$ between $a_{2^{i-1}}$ exclusively and $a_{2^i}$ inclusively. Return the index and stop.



                            2. Is $xge a_{n-2^i+1}$?


                              • If yes, do a binary search for $x$ between $a_{n-2^{i}+1}$ inclusively and $a_{n-2^{i-1}+1}$ exclusively.
                                Return the index and stop.



                            3. increase $i$ by 1.








                          share|cite|improve this answer











                          $endgroup$
















                            1












                            1








                            1





                            $begingroup$

                            You can apply binary expanding search starting from both ends of the given array.



                            For ease of statement, I will assume $n=2^k$ for some integer $kge0$. Otherwise, a boundary check can be included in step 3.1. I will assume the given array is sorted from small to large; otherwise, one comparison between $a_1$ and $a_n$ can be done to find the sorting order and the procedure can be adjusted accordingly.




                            1. Check if $x=a_1$ or $x=a_n$. If yes, return 1 or $n$ accordingly and stop.

                            2. Let $i=1$.

                            3. Loop the following.


                              1. Is $xle a_{2^i}$?


                                • If yes, do a binary search for $x$ between $a_{2^{i-1}}$ exclusively and $a_{2^i}$ inclusively. Return the index and stop.



                              2. Is $xge a_{n-2^i+1}$?


                                • If yes, do a binary search for $x$ between $a_{n-2^{i}+1}$ inclusively and $a_{n-2^{i-1}+1}$ exclusively.
                                  Return the index and stop.



                              3. increase $i$ by 1.








                            share|cite|improve this answer











                            $endgroup$



                            You can apply binary expanding search starting from both ends of the given array.



                            For ease of statement, I will assume $n=2^k$ for some integer $kge0$. Otherwise, a boundary check can be included in step 3.1. I will assume the given array is sorted from small to large; otherwise, one comparison between $a_1$ and $a_n$ can be done to find the sorting order and the procedure can be adjusted accordingly.




                            1. Check if $x=a_1$ or $x=a_n$. If yes, return 1 or $n$ accordingly and stop.

                            2. Let $i=1$.

                            3. Loop the following.


                              1. Is $xle a_{2^i}$?


                                • If yes, do a binary search for $x$ between $a_{2^{i-1}}$ exclusively and $a_{2^i}$ inclusively. Return the index and stop.



                              2. Is $xge a_{n-2^i+1}$?


                                • If yes, do a binary search for $x$ between $a_{n-2^{i}+1}$ inclusively and $a_{n-2^{i-1}+1}$ exclusively.
                                  Return the index and stop.



                              3. increase $i$ by 1.









                            share|cite|improve this answer














                            share|cite|improve this answer



                            share|cite|improve this answer








                            edited 12 hours ago

























                            answered 12 hours ago









                            Apass.JackApass.Jack

                            10.5k1939




                            10.5k1939






























                                draft saved

                                draft discarded




















































                                Thanks for contributing an answer to Computer Science Stack Exchange!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                Use MathJax to format equations. MathJax reference.


                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function () {
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcs.stackexchange.com%2fquestions%2f104291%2fgiven-a-sorted-array-with-n-elements-and-element-x-that-is-inside-the-array-at-p%23new-answer', 'question_page');
                                }
                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown







                                Popular posts from this blog

                                How to make a Squid Proxy server?

                                第一次世界大戦

                                Touch on Surface Book