Java O(n) solution with explanation in comments
\tpublic int minSubarray(int[] nums, int p) {\n        // If sum(all) % p = t, we need to find the smallest segment that sum(seg) % p = t\n        int len = num
\tpublic int minSubarray(int[] nums, int p) {\n        // If sum(all) % p = t, we need to find the smallest segment that sum(seg) % p = t\n        int len = nums.length, shortest = len;\n        long sum = 0;                               // Need long here as the total sum may exceed Integer.MAX_VALUE\n        // Suppose with j > i, sum(i) = mp + x and sum(j) = np + y. So sum(j - i) = (n - m)p + (y - x)\n        // In this case if (y - x) == t || (y + p - x) == t, sum(j - i) % p = t and we can remove the segment (j - i)\n        Map<Integer, Integer> remIndexMap = new HashMap<> ();       // Stores each remainder with its latest index\n        remIndexMap.put(0, -1);         // Initialize remainder 0 with index -1\n        for(int num: nums)\n            sum += num;\n        \n        int t = (int) (sum % p);        // Get the target remainder first\n        if(t == 0)              return 0;\n        sum = 0;\n        \n        for(int i = 0; i < len; i ++) {\n            sum += nums[i];\n            int y = (int) (sum % p);    // Need to find the last index with remainder x so that (y - x) == t || (y + p - x) == t\n            if(remIndexMap.containsKey(y - t))\n                shortest = Math.min(shortest, i - remIndexMap.get(y - t));\n            if(remIndexMap.containsKey(y + p - t))\n                shortest = Math.min(shortest, i - remIndexMap.get(y + p - t));\n            \n            remIndexMap.put(y, i);      // Update the rem with its index\n        }\n        \n        return (shortest == len) ? -1 : shortest;\n    }\n
[]